mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 18:32:22 +00:00
docs(class): 添加 in 运算符
This commit is contained in:
parent
05031368ba
commit
89370afc1c
111
docs/class.md
111
docs/class.md
@ -924,6 +924,117 @@ FakeMath.#computeRandomNumber() // 报错
|
|||||||
|
|
||||||
上面代码中,`#totallyRandomNumber`是私有属性,`#computeRandomNumber()`是私有方法,只能在`FakeMath`这个类的内部调用,外部调用就会报错。
|
上面代码中,`#totallyRandomNumber`是私有属性,`#computeRandomNumber()`是私有方法,只能在`FakeMath`这个类的内部调用,外部调用就会报错。
|
||||||
|
|
||||||
|
### in 运算符
|
||||||
|
|
||||||
|
`try...catch`结构可以用来判断是否存在某个私有属性。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
use(obj) {
|
||||||
|
try {
|
||||||
|
obj.#foo;
|
||||||
|
} catch {
|
||||||
|
// 私有属性 #foo 不存在
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const a = new A();
|
||||||
|
a.use(a); // 报错
|
||||||
|
```
|
||||||
|
|
||||||
|
上面示例中,类`A`并不存在私有属性`#foo`,所以`try...catch`报错了。
|
||||||
|
|
||||||
|
这样的写法很麻烦,可读性很差,V8 引擎改进了`in`运算符,使它也可以用来判断私有属性。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
use(obj) {
|
||||||
|
if (#foo in obj) {
|
||||||
|
// 私有属性 #foo 存在
|
||||||
|
} else {
|
||||||
|
// 私有属性 #foo 不存在
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面示例中,`in`运算符判断当前类`A`的实例,是否有私有属性`#foo`,如果有返回`true`,否则返回`false`。
|
||||||
|
|
||||||
|
`in`也可以跟`this`一起配合使用。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
#foo = 0;
|
||||||
|
m() {
|
||||||
|
console.log(#foo in this); // true
|
||||||
|
console.log(#bar in this); // false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
注意,判断私有属性时,`in`只能用在定义该私有属性的类的内部。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
#foo = 0;
|
||||||
|
static test(obj) {
|
||||||
|
console.log(#foo in obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
A.test(new A()) // true
|
||||||
|
A.test({}) // false
|
||||||
|
|
||||||
|
class B {
|
||||||
|
#foo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
A.test(new B()) // false
|
||||||
|
```
|
||||||
|
|
||||||
|
上面示例中,类`A`的私有属性`#foo`,只能在类`A`内部使用`in`运算符判断,而且只对`A`的实例返回`true`,对于其他对象都返回`false`。
|
||||||
|
|
||||||
|
子类从父类继承的私有属性,也可以使用`in`运算符来判断。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
#foo = 0;
|
||||||
|
static test(obj) {
|
||||||
|
console.log(#foo in obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SubA extend A {};
|
||||||
|
|
||||||
|
A.test(new SubA()) // true
|
||||||
|
```
|
||||||
|
|
||||||
|
上面示例中,`SubA`从父类继承了私有属性`#foo`,`in`运算符也有效。
|
||||||
|
|
||||||
|
注意,`in`运算符对于`Object.create()`、`Object.setPrototypeOf`形成的继承,是无效的,因为这种继承不会传递私有属性。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
class A {
|
||||||
|
#foo = 0;
|
||||||
|
static test(obj) {
|
||||||
|
console.log(#foo in obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const a = new A();
|
||||||
|
|
||||||
|
const o1 = Object.create(a);
|
||||||
|
A.test(o1) // false
|
||||||
|
A.test(o1.__proto__) // true
|
||||||
|
|
||||||
|
const o2 = {};
|
||||||
|
Object.setPrototypeOf(o2, A);
|
||||||
|
A.test(o2) // false
|
||||||
|
A.test(o2.__proto__) // true
|
||||||
|
```
|
||||||
|
|
||||||
|
上面示例中,对于修改原型链形成的继承,子类都取不到父类的私有属性,所以`in`运算符无效。
|
||||||
|
|
||||||
## new.target 属性
|
## new.target 属性
|
||||||
|
|
||||||
`new`是从构造函数生成实例对象的命令。ES6 为`new`命令引入了一个`new.target`属性,该属性一般用在构造函数之中,返回`new`命令作用于的那个构造函数。如果构造函数不是通过`new`命令或`Reflect.construct()`调用的,`new.target`会返回`undefined`,因此这个属性可以用来确定构造函数是怎么调用的。
|
`new`是从构造函数生成实例对象的命令。ES6 为`new`命令引入了一个`new.target`属性,该属性一般用在构造函数之中,返回`new`命令作用于的那个构造函数。如果构造函数不是通过`new`命令或`Reflect.construct()`调用的,`new.target`会返回`undefined`,因此这个属性可以用来确定构造函数是怎么调用的。
|
||||||
|
Loading…
x
Reference in New Issue
Block a user