问题描述
更新:我无法回答这个问题,因为它已被锁定,但我在底部有自己的解决方案,与 Jonas' answer
合作假设我在原型中添加了这个。我将使用 HTMLElement 作为示例。
HTMLElement.prototype.MyNamespaceGetThis = function() {
return this;
}
document.body.MyNamespaceGetThis()
将返回 document.body
但是如果我想把它嵌套在一个对象中
HTMLElement.prototype.MyNamespace = {};
HTMLElement.prototype.MyNamespace.GetThis = function() {
return this;
}
document.body.MyNameSpace.GetThis()
将返回 document.body
的 MyNameSpace
({GetThis: ƒ}
)
有没有办法让 this
或任何变量返回对基础对象的引用? document.body
在这种情况下?
我尝试了一些变体,例如
HTMLElement.prototype.MyNameSpace = (function() {
let that = this
let obj = Object.defineProperties({},{GetThis: {
value: function() {
console.log(that)
},enumerable: false}})
return obj;
})()
但是由于完全可以理解的原因,这失败了。该函数仅运行一次并返回对 window
我已经用 .bind()
尝试了一些实验,但出于可预见的原因,没有一个能返回想要的结果。
我的解决方案
我不喜欢 Jonas 的回答的是,它与 MyNamespace().method
基本相同,其中 MyNamespace
返回一组方法。
持久化成员也是不可能的。如果我想存储成员数据,我需要一个单独的对象来做这件事,但我不喜欢那样。
我的解决方案是使用 class
,然后以一种特殊的内存轻量方式调用它。
class MyNamespace {
constructor(parent) {
this.parent = parent;
}
GetThis() {
return this.parent;
}
}
然后,对于这个例子,你像这样将它添加到 HTMLElement 原型
Object.defineProperties(HTMLElement.prototype,{
MyNamespace: {
enumerable: false,writeable: true,get: function() {
let ret = new MyNamespace(this);
Object.defineProperty(this,'MyNamespace',{
enumerable: false,writeable: false,// note about this
value: ret
});
return ret;
},enumerable: false,writeable: false
},})
第一次调用 document.body.MyNamespace.GetThis()
将返回类 MyNamespace
的一个新实例,然后从中调用 GetThis()
。它还将更改 document.body
的 MyNamespace
以直接引用创建的实例,而不是每次都创建一个新实例。这意味着持久数据。
我喜欢的其他一点是,每个元素都不会携带完整的 MyNamespace
实例,除非它在文档的生命周期中被调用。
更新引用后,我将其设置为冻结,以免被覆盖,但很容易想象人们可能需要 destroy
方法的位置。您可以将 writable
更改为 true 之类的。
class MyNamespace {
constructor(parent) {
this.parent = parent;
}
GetThis() {
return this.parent;
}
destroy() {
Object.defineProperties(HTMLElement.prototype,{
MyNamespace: {
enumerable: false,get: MyNamespace.factory(this,true),writeable: false
},})
}
renew() {
this.parent.MyNamespace = MyNamespace.factory(this.parent,true)
// HTMLElement.prototype.MyNamespace can also be set
// to MyNamespace.factory(this)
}
static factory(parent,writeable) {
return Object.defineProperty(parent,{
enumerable: false,writeable: writeable,value: new MyNamespace(parent)
}).MyNamespace;
}
}
解决方法
将 MyNamespace
转换为 getter 并存储对父级的引用:
function Namespace(parent) {
return {
parent,/* Your functions here */
};
}
Object.defineProperty(HTMLElement.prototype,"namespace",{
get() { return Namespace(this); },});
console.log(
document.body.namespace.parent === document.body // true
);