本文介绍了与这个相比,超级市场的价值是如何确定的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
this
由执行上下文确定
我习惯了JavaScript中this
的特性。在下面的示例中,this
由执行上下文确定。尽管getProtoPropViaThis
函数是在x
上定义的,但this
的值取决于函数的调用方式:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">const xProto = {
protoProp: "x",
};
const x = {
getProtoPropViaThis() {
return this.protoProp;
},
}
Object.setPrototypeOf(x, xProto);
const yProto = {
protoProp: "y",
};
const y = {
getProtoPropViaThis: x.getProtoPropViaThis,
}
Object.setPrototypeOf(y, yProto);
console.log( x.getProtoPropViaThis() ); // Output: x
console.log( y.getProtoPropViaThis() ); // Output: y
super
不受执行上下文影响?
我使用super
已经有一段时间了,但总是在类的上下文中使用。所以,当我最近读到an article时,我感到惊讶,从切线上看,super
似乎并不遵循与this
相同的规则。不知何故,以一种我不完全理解的方式(尽管读了几遍ECMAScript 2021 language docs),super
设法抓住了它最初的引用:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
const xProto = {
protoProp: "x",
};
const x = {
getProtoPropViaSuper() {
return super.protoProp;
},
}
Object.setPrototypeOf(x, xProto);
const yProto = {
protoProp: "y",
};
const y = {
getProtoPropViaSuper: x.getProtoPropViaSuper,
}
Object.setPrototypeOf(y, yProto);
console.log( x.getProtoPropViaSuper() ); // Output: x
console.log( y.getProtoPropViaSuper() ); // Output: x
请注意,y
在其原型链中的任何位置都没有x
或xProto
,但在调用y.getProtoPropViaSuper()
时仍是
xProto
的属性
差异明显,Object.assign
再举一个例子,以下命令根本不起作用:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
const xProto = {
protoProp: "x",
};
const x = Object.assign(Object.create(xProto), {
getProtoPropViaSuper() {
return super.protoProp;
},
});
console.log(x.getProtoPropViaSuper());
super
的值是对象的原型,而不是x
的原型,因此上面的示例仅打印undefined
。
跟随文档
12.3.7.1 Runtime Semantics: Evaluation
12.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )
8.1.1.3.5 GetSuperBase ( )
最后:
8.1.1.3 Function Environment Records,Table 17
按照本文档,
getProtoPropViaSuper
似乎应该作为一种方法绑定到
y
,但可能在创建
x
对象时以某种方式存储了该绑定,即使在将函数分配给
y
时也是如此。然而,我还无法从这些文档中分析这种情况在何时何地发生。如果有人能用通俗易懂的语言解释一下这一行为,我将不胜感激。
super
如何确定其价值?它似乎如何保持其原始的
super
上下文?如果它保留原始对象,则可能会导致内存泄漏,因为原始对象无法被垃圾收集。但也许
super
引用是在准编译时确定的?(我之所以这样说,是因为引用仍然可以通过
Object.setPrototypeOf
更改)
推荐答案
是的,这正是发生的事情。getProtoPropViaSuper
方法基本上关闭了在其中定义它的对象。它存储在函数本身的内部[[HomeObject]]槽中,这就是为什么如果将方法分配给不同的对象,或者更重要的是在不同的对象上继承它,它会被保留。对于Object文本中的方法定义,它是由文本创建的对象;对于class
ES中的方法定义,它是类的.prototype
对象。
不,它不会导致比其他闭包更多的内存泄漏。当然,该方法可以防止其home对象被垃圾回收,但是考虑到home对象是一个原型对象--至少在正常使用中--它也在通常调用该方法的对象的原型链中被引用,所以这不是问题。
它接受其绑定的home对象的原型,该对象是在其中定义方法的对象。但是请注意,访问super
上的属性不会返回对该对象的属性的普通引用,而是一个特殊引用,当调用该引用(方法)时,它将把当前作用域的this
值作为方法调用的this
参数,而不是原型对象。简而言之,
const x = {
method() {
super.something(a, b);
}
}
脱糖至
const x = {
method() {
Object.getPrototypeOf(x).something.call(this, a, b);
}
}
和
class X {
method() {
super.something(a, b);
}
}
脱糖至
class X {
method() {
Object.getPrototypeOf(X.prototype).something.call(this, a, b);
}
}
这篇关于与这个相比,超级市场的价值是如何确定的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!