MDN page about set
似乎表明了一个
[ECMAScript 2015] setter不得出现在对象文字中...带有相同属性的数据条目。
但是,当使用super关键字时,这似乎不再适用。
class Foo {
constructor(bar){
this.bar = bar
}
set bar(newBar){
if (!newBar.match(/\w+/))
throw Error("Invalid bar value")
// I can use super despite not being a derived class.
return super.bar = newBar
}
}
const baz = new Foo("Baz")
baz.bar = "new value" // No recursion
这似乎是一个有用的功能,因为该属性不必通过在其前面添加下划线来“隐藏”。另外,我不必弄乱属性可枚举性,以避免“隐藏”版本在循环或序列化中显示。
但set
语法有点像黑盒子,我无法分辨它究竟在做什么。
我在这里打破一些东西还是可以使用?
还有什么是super
在这里引用?
这似乎是一个有用的功能,因为该属性不必通过在其前面添加下划线或其他内容来“隐藏”。另外,我不必弄乱属性可枚举性,以避免“隐藏”版本在循环或序列化中显示。
不,它没用。这是一个充其量的黑客,并没有做你期望的。
这里根本没有隐藏的东西。您正在实例上创建一个名为bar
的新属性,隐藏您在原型上定义的任何getter / setter。第二个作业没有得到你的二传手。实例属性也是普通的可枚举属性,因此它将显示在for in
循环和序列化中。
那么什么是“超级”引用?
super
关键字指的是定义方法(或设置器)的对象的原型,即Object.getPrototypeOf(Foo.prototype)
。这是你的情况下的Object.prototype
,因为你的class Foo
没有extend
任何东西。
将在该原型上查找.foo
访问,并且通常会找到您从父类或其他东西继承的方法。当使用它时,属性引用super.foo
将使操作的接收者(即方法调用中的this
关键字是什么)是当前的this
实例,而不是原型。
在您的情况下,它不是方法调用而是分配。这可以运行从父类继承的setter,但是在你的情况下没有Object.prototype.foo
属性,所以它将回退到目标上的标准赋值 - 并且该目标是baz
实例本身,其中将创建新的自己的属性。
所以不,使用它是不对的。