重学JS-2-数据类型和变量

173 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

前端开发的第三年,突然发现,对于JS,我还有很多不懂的地方,趁着最近需求少,不如静下心来,从头把JS再学一遍,查漏补缺。

本系列以廖雪峰的《JavaScript教程》和《现代 JavaScript 教程》两个电子书作为线索,对其中需要进一步了解的知识,会阅读更多的文章,并作为扩展知识记录下来。

新手建议先阅读上面两个电子书,本系列更适合用来复习旧知识查漏补缺

通过下面的思维导图,我们先对JavaScript的数据类型和变量有一些基本的了解。

思维导图

《JavaScript教程》思维导图

通过下文的扩展阅读,我们进一步去了解更进一步的知识。

var变量提升

var的变量提升

console.log(a) // undefined
var a = 12

let的暂时性死区

(function() {
  // let x 此时暂时性死区开始
  console.log(x); // Uncaught ReferenceError: x is not defined
  //暂时性死区结束
  let x = 'child value' 
}())

IIFE旧时var创建块级作用域的方法

原理是:创建了一个函数表达式并立即调用

// 创建 IIFE 的方法

(function() {
  alert("Parentheses around the function");
})();

(function() {
  alert("Parentheses around the whole thing");
}());

!function() {
  alert("Bitwise NOT operator starts the expression");
}();

+function() {
  alert("Unary plus starts the expression");
}();

参考文章

旧时的 "var"

因为说let没有变量提升,我被嘲笑了

深入理解箭头函数

箭头函数没有this

箭头函数没有this,如果访问this,会取到外层的this

let group = {
  title: "Our Group",
  students: ["John", "Pete", "Alice"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

group.showList();

箭头函数没有arguments

在箭头函数内获取的arguments都是来自父作用域的。

例如下面的例子,defer(f, ms) 获得了一个函数,并返回一个包装器,该包装器将调用延迟 ms 毫秒,其中箭头函数的arguments是返回的函数的arguments

function defer(f, ms) {
  return function() {
    setTimeout(() => f.apply(this, arguments), ms);
  };
}

function sayHi(who) {
  alert('Hello, ' + who);
}

let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("John"); // 2 秒后显示:Hello, John

是否使用箭头函数,参考下面这个图,来自《You-Dont-Know-JS》

fig1

参考文章

深入理解箭头函数

You-Dont-Know-JS

JS的循环

常见的循环参考这篇讲的比较全的问题JS常用的循环遍历你会几种

for-in为什么被ESLint告警

eslint有一条guard-for-in规则,这条规则要求for-in语句要包含一个if判断来判断objectkey是否存在,以避免一些意外的错误。

此规则的错误代码示例:

/*eslint guard-for-in: "error"*/

for (key in foo) {
    doSomething(key);
}

此规则的正确代码示例:

/*eslint guard-for-in: "error"*/

for (key in foo) {
    if (Object.prototype.hasOwnProperty.call(foo, key)) {
        doSomething(key);
    }
}

for (key in foo) {
    if ({}.hasOwnProperty.call(foo, key)) {
        doSomething(key);
    }
}

当然除了加判断,也可以直接改用Object.keysforEach

currentValues= {hey:1212, git:1212, nmo:12121}

Object.keys(currentValues).forEach(function(key) {
  yield put(setCurrentValue(key, currentValues[key]));
})

参考文章

JS常用的循环遍历你会几种

guard-for-in

ESLint doesn't allow for in