diff --git a/docs/class.md b/docs/class.md index f4f1fc4..ccd924f 100644 --- a/docs/class.md +++ b/docs/class.md @@ -31,7 +31,7 @@ class Point { } toString() { - return '('+this.x+', '+this.y+')'; + return '(' + this.x + ', ' + this.y + ')'; } } diff --git a/docs/function.md b/docs/function.md index 39b17ab..982c064 100644 --- a/docs/function.md +++ b/docs/function.md @@ -839,7 +839,7 @@ setTimeout(() => console.log(timer.seconds), 3100) 上面代码中,`Timer`函数内部的`setInterval`调用了`this.seconds`属性,通过箭头函数让`this`总是指向Timer的实例对象。否则,输出结果是0,而不是3。 -`this`指向的固定化,并不是因为箭头函数内部有绑定`this`的机制,实际原因是箭头函数根本没有自己的`this`,导致内部的`this`就是外层代码块的`this`。 +`this`指向的固定化,并不是因为箭头函数内部有绑定`this`的机制,实际原因是箭头函数根本没有自己的`this`,导致内部的`this`就是外层代码块的`this`。正是因为它没有`this`,所以也就不能用作构造函数。 请问下面的代码之中有几个`this`? @@ -875,7 +875,7 @@ foo( 2, 4, 6, 8 ); 上面代码中,箭头函数内部的变量`arguments`,其实是函数`foo`的`arguments`变量。 -另外,由于箭头函数内部没有`this`,所以当然也就不能用`call()`、`apply()`、`bind()`这些方法去改变`this`的指向。 +另外,由于箭头函数没有自己的`this`,所以当然也就不能用`call()`、`apply()`、`bind()`这些方法去改变`this`的指向。 长期以来,JavaScript语言的`this`对象一直是一个令人头痛的问题,在对象方法中使用`this`,必须非常小心。箭头函数”绑定”`this`,很大程度上解决了这个困扰。 diff --git a/docs/iterator.md b/docs/iterator.md index 22393bd..65c004c 100644 --- a/docs/iterator.md +++ b/docs/iterator.md @@ -719,11 +719,9 @@ for (var index in myArray) { for...in循环有几个缺点。 -1)数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。 - -2)for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 - -3)某些情况下,for...in循环会以任意顺序遍历键名。 +- 数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。 +- for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 +- 某些情况下,for...in循环会以任意顺序遍历键名。 总之,`for...in`循环主要是为遍历对象而设计的,不适用于遍历数组。 diff --git a/docs/object.md b/docs/object.md index 7337e34..3b860f7 100644 --- a/docs/object.md +++ b/docs/object.md @@ -491,6 +491,47 @@ Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, 'foo').enumerable 总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用`for...in`循环,而用`Object.keys()`代替。 +## 属性的遍历 + +ES6一共有6种方法可以遍历对象的属性。 + +**(1)for...in** + +`for...in`循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。 + +**(2)Object.keys(obj)** + +`Object.keys`返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。 + +**(3)Object.getOwnPropertyNames(obj)** + +`Object.getOwnPropertyNames`返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。 + +**4)Object.getOwnPropertySymbols(obj)** + +`Object.getOwnPropertySymbols`返回一个数组,包含对象自身的所有Symbol属性。 + +**(5)Reflect.ownKeys(obj)** + +`Reflect.ownKeys`返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。 + +**(6)Reflect.enumerate(obj)** + +`Reflect.enumerate`返回一个Iterator对象,遍历对象自身的和继承的所有可枚举属性(不含Symbol属性),与`for...in`循环相同。 + +以上的6种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。 + +- 首先遍历所有属性名为数值的属性,按照数字排序。 +- 其次遍历所有属性名为字符串的属性,按照生成时间排序。 +- 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。 + +```javascript +Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 }) +// ['2', '10', 'b', 'a', Symbol()] +``` + +上面代码中,`Reflect.ownKeys`方法返回一个数组,包含了参数对象的所有属性。这个数组的属性次序是这样的,首先是数值属性`2`和`10`,其次是字符串属性`b`和`a`,最后是Symbol属性。 + ## `__proto__`属性,Object.setPrototypeOf(),Object.getPrototypeOf() **(1)`__proto__`属性**