mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
docs(symbol): edit simbol.hasInstance
This commit is contained in:
parent
e2c81a77d9
commit
fe3446c157
@ -753,7 +753,23 @@ colors.length = 0;
|
||||
colors[0] // "red"
|
||||
```
|
||||
|
||||
之所以会发生这种情况,是因为子类无法获得原生构造函数的内部属性,通过`Array.apply()`或者分配给原型对象都不行。ES5是先新建子类的实例对象`this`,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数。比如,Array构造函数有一个内部属性`[[DefineOwnProperty]]`,用来定义新属性时,更新`length`属性,这个内部属性无法在子类获取,导致子类的`length`属性行为不正常。
|
||||
之所以会发生这种情况,是因为子类无法获得原生构造函数的内部属性,通过`Array.apply()`或者分配给原型对象都不行。原生构造函数会忽略`apply`方法传入的`this`,也就是说,原生构造函数的`this`无法绑定,导致拿不到内部属性。
|
||||
|
||||
ES5是先新建子类的实例对象`this`,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数。比如,Array构造函数有一个内部属性`[[DefineOwnProperty]]`,用来定义新属性时,更新`length`属性,这个内部属性无法在子类获取,导致子类的`length`属性行为不正常。
|
||||
|
||||
下面的例子中,我们想让一个普通对象继承`Error`对象。
|
||||
|
||||
```javascript
|
||||
var e = {};
|
||||
|
||||
Object.getOwnPropertyNames(Error.call(e))
|
||||
// [ 'stack' ]
|
||||
|
||||
Object.getOwnPropertyNames(e)
|
||||
// []
|
||||
```
|
||||
|
||||
上面代码中,我们想通过`Error.call(e)`这种写法,让普通对象`e`具有`Error`对象的实例属性。但是,`Error.call()`完全忽略传入的第一个参数,而是返回一个新对象,`e`本身没有任何变化。这证明了`Error.call(e)`这种写法,无法继承原生构造函数。
|
||||
|
||||
ES6允许继承原生构造函数定义子类,因为ES6是先新建父类的实例对象`this`,然后再用子类的构造函数修饰`this`,使得父类的所有行为都可以继承。下面是一个继承`Array`的例子。
|
||||
|
||||
|
@ -142,7 +142,7 @@ function bar(x = 2, y = x) {
|
||||
bar(); // [2, 2]
|
||||
```
|
||||
|
||||
ES6规定暂时性死区和修订变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在ES5是很常见的,现在有了这种规定,避免此类错误就很容易了。
|
||||
ES6规定暂时性死区和`let`、`const`语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在ES5是很常见的,现在有了这种规定,避免此类错误就很容易了。
|
||||
|
||||
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
|
||||
|
||||
@ -359,7 +359,7 @@ function f() { console.log('I am outside!'); }
|
||||
|
||||
注意,上面三条规则只对ES6的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作`let`处理。
|
||||
|
||||
前面那段代码,在老版本的Chrome环境下运行会报错。
|
||||
前面那段代码,在Chrome环境下运行会报错。
|
||||
|
||||
```javascript
|
||||
// ES6的浏览器环境
|
||||
|
@ -774,7 +774,16 @@ function SaferHTML(templateData) {
|
||||
}
|
||||
```
|
||||
|
||||
上面代码中,经过`SaferHTML`函数处理,HTML字符串的特殊字符都会被转义。
|
||||
上面代码中,`sender`变量往往是用户提供的,经过`SaferHTML`函数处理,里面的特殊字符都会被转义。
|
||||
|
||||
```javascript
|
||||
var sender = '<script>alert("abc")</script>'; // 恶意代码
|
||||
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;
|
||||
|
||||
message
|
||||
// <p><script>alert("abc")</script> has sent you a message.</p>
|
||||
```
|
||||
|
||||
|
||||
标签模板的另一个应用,就是多语言转换(国际化处理)。
|
||||
|
||||
|
@ -453,6 +453,22 @@ class MyClass {
|
||||
[1, 2, 3] instanceof new MyClass() // true
|
||||
```
|
||||
|
||||
上面代码中,`MyClass`是一个类,`new MyClass()`会返回一个实例。该实例的`Symbol.hasInstance`方法,会在进行`instanceof`运算时自动调用,判断左侧的运算子是否为`Array`的实例。
|
||||
|
||||
下面是另一个例子。
|
||||
|
||||
```javascript
|
||||
class Even {
|
||||
static [Symbol.hasInstance](obj) {
|
||||
return Number(obj) % 2 === 0;
|
||||
}
|
||||
}
|
||||
|
||||
1 instanceof Even // false
|
||||
2 instanceof Even // true
|
||||
12345 instanceof Even // false
|
||||
```
|
||||
|
||||
### Symbol.isConcatSpreadable
|
||||
|
||||
对象的`Symbol.isConcatSpreadable`属性等于一个布尔值,表示该对象使用`Array.prototype.concat()`时,是否可以展开。
|
||||
|
Loading…
x
Reference in New Issue
Block a user