![](/img/trans.png)
[英]How do I spread an object (class instance properties) to the parent's super constructor?
[英]How do I retain the properties of a Javascript object while changing the object's constructor to an instance function
我在 javascript 中有一个实例函数,为了命名约定,我添加了其他实例函数作为第一个实例函数对象的属性。 下面的工作 JavaScript 更好地说明了这一点。
var MyModule = (function() { // instance function
return function() {
console.log("ran MyModule");
}
}());
MyModule.RelatedModule = (function() { //second instance function is a property of first instance function object
return function() {
console.log("ran RelatedModule");
}
}())
var inst1 = new MyModule(), // logs "ran MyModule"
inst2 = new MyModule.RelatedModule(); // logs "ran RelatedModule"
这按预期工作,没有错误。 我想做的是在创建MyModule
对象后为MyModule
创建函数定义,有人可以帮我实现吗? 我在下面说明了我的尝试。
var MyModule = {}; // create object first, try to set a constructor on it later
MyModule.RelatedModule = (function() { // add properties to the MyModule object
return function() {
console.log("ran RelatedModule");
}
}())
// the following does not work, I'd like to set the `MyModule` constructor instance function and retain the `MyModule.RelatedModule` property
MyModule.constructor = (function() {
return function() {
console.log("ran MyModule");
}
}());
那么,如何保留对象的属性并更改其构造函数呢?
你混淆了几个概念。 在您的第一个示例中, MyModule
没有构造函数,它是一个构造函数。 也就是说,它是一个函数对象,您打算与new
运算符一起使用来创建新对象。 这些对象将具有指向MyModule
(创建它们的函数)的constructor
属性。 更改此constructor
属性不会对MyModule
产生任何影响; 该属性只是一个指向实例化对象的函数的指针。
换句话说,您不能更改MyModule
的构造函数。 那是毫无意义的说法。
现在,当你写:
var MyModule = {};
...您创建一个新对象,其constructor
属性为Object()
:
console.log(MyModule.constructor) // prints Object()
同样,更改此属性实际上并没有多大作用(除了混淆一些有用的簿记)。
此时MyModule
只是一个普通的旧对象。 它根本不是一个函数。 这就是为什么您会收到“不是函数”错误的原因。 因为它不是,但你正试图像使用它一样使用它。 如果您希望该名称引用一个函数(即指向不同的对象),那么您将丢失对先前设置的任何属性的所有引用,因为您指向的是一个全新的对象。
就是那样子。
现在,您可以保存对包含所有先前设置的属性的对象的引用,并在将该名称指向函数后将它们复制回MyObject
。 但我不确定重点是什么。
lwburk 所说的一切都是正确的,但是,下面的内容是您想要完成的,它通过调用MyModule
的init()
方法来实现。
var MyModule = function(){
return this.init();
};
MyModule.prototype.init = function(){};
MyModule.RelatedModule = (function() { // add properties to the MyModule object
return function() {
console.log("ran RelatedModule");
};
}());
MyModule.prototype.init = function(){
console.log("ran MyModule");
};
var inst1 = new MyModule(),
inst2 = new MyModule.RelatedModule();
首先,存在一个已知的浏览器错误,其中(构造对象的)构造函数属性使用原型正确解析,但未应用于对象构造。 因此,您需要以下 polyfill:
function NEW(clas, ...args)
{
let res = Object.setPrototypeOf({}, clas.prototype);
res.constructor.apply(res, args);
return res;
}
其次,您需要设置MyModule.prototype.constructor
而不是MyModule.constructor
。 原因是MyModule.constructor
是构造新类的函数,而不是构造新对象的函数。 (请参阅: 为什么一个类在 JavaScript 中有一个“构造函数”字段? )
换句话说:
var MyModule = {}; // create object first, try to set a constructor on it later
MyModule.RelatedModule = (function() { // add properties to the MyModule object
return function() {
console.log("ran RelatedModule");
}
}())
// set the `MyModule` prototype.constructor instance function and retain the `MyModule.RelatedModule` property
MyModule.prototype = {
constructor() {
console.log("ran MyModule");
}}
var inst1 = NEW(MyModule), // logs "ran MyModule"
inst2 = NEW(MyModule.RelatedModule); // logs "ran RelatedModule"
简短的回答是你不能这样做。 但是,您可以更改对象的原型。 查看此答案以深入了解如何重新考虑使用此约束的方法: Changing constructor in JavaScript
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.