是否可以在原型中的对象中嵌套函数并访问基础对象?
Is it possible to nest functions in an object in a prototype and access the base object?
更新:我无法回答这个问题,因为它已被锁定,但我在底部有自己的解决方案,与
一起工作
假设我在原型中添加了这个。我将使用 HTMLElement 作为示例。
HTMLElement.prototype.MyNamespaceGetThis = function() {
return this;
}
document.body.MyNamespaceGetThis()
将 return document.body
但是如果我想把它嵌套在一个对象中
HTMLElement.prototype.MyNamespace = {};
HTMLElement.prototype.MyNamespace.GetThis = function() {
return this;
}
document.body.MyNameSpace.GetThis()
将 return document.body
的 MyNameSpace
({GetThis: ƒ}
)
有没有办法使 this
或任何变量 return 成为对基础对象的引用? document.body
在这种情况下?
我尝试了一些变体,例如
HTMLElement.prototype.MyNameSpace = (function() {
let that = this
let obj = Object.defineProperties({}, {GetThis: {
value: function() {
console.log(that)
},
enumerable: false}})
return obj;
})()
但是由于完全可以理解的原因,这失败了。该函数只有 运行 一次并且 return 是对 window
的引用
我用 .bind()
尝试了一些实验,但出于可预见的原因 none return 想要的结果。
我的解决方案
我不喜欢 Jonas 的答案,因为它与 MyNamespace().method
基本相同,其中 MyNamespace
return 是一组方法。
持久成员也是不可能的。如果我想存储会员数据,我需要一个单独的对象来做这件事,我不喜欢那样。
我的解决方案是使用 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()
将 return class 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, writeable: true,
get: MyNamespace.factory(this, true),
enumerable: false, 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, 'MyNamespace', {
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
);
更新:我无法回答这个问题,因为它已被锁定,但我在底部有自己的解决方案,与
一起工作
假设我在原型中添加了这个。我将使用 HTMLElement 作为示例。
HTMLElement.prototype.MyNamespaceGetThis = function() {
return this;
}
document.body.MyNamespaceGetThis()
将 return document.body
但是如果我想把它嵌套在一个对象中
HTMLElement.prototype.MyNamespace = {};
HTMLElement.prototype.MyNamespace.GetThis = function() {
return this;
}
document.body.MyNameSpace.GetThis()
将 return document.body
的 MyNameSpace
({GetThis: ƒ}
)
有没有办法使 this
或任何变量 return 成为对基础对象的引用? document.body
在这种情况下?
我尝试了一些变体,例如
HTMLElement.prototype.MyNameSpace = (function() {
let that = this
let obj = Object.defineProperties({}, {GetThis: {
value: function() {
console.log(that)
},
enumerable: false}})
return obj;
})()
但是由于完全可以理解的原因,这失败了。该函数只有 运行 一次并且 return 是对 window
我用 .bind()
尝试了一些实验,但出于可预见的原因 none return 想要的结果。
我的解决方案
我不喜欢 Jonas 的答案,因为它与 MyNamespace().method
基本相同,其中 MyNamespace
return 是一组方法。
持久成员也是不可能的。如果我想存储会员数据,我需要一个单独的对象来做这件事,我不喜欢那样。
我的解决方案是使用 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()
将 return class 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, writeable: true,
get: MyNamespace.factory(this, true),
enumerable: false, 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, 'MyNamespace', {
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
);