我有一个JS类,它有一些默认属性。我希望能够传入一个options对象来覆盖默认值以及一些未默认的其他对象。我在构造函数中使用lodash的extend
方法来完成此任务。
其中一个默认属性是数组。如果我实例化第一个实例并将新值推入数组,那么当我实例化第二个对象时,默认数组包含我推入第一个实例的对象。
以此代码为例......
MyClass = (function() {
var defaults = {
myArr: [],
myProp: 'I\'m a default value'
};
function MyClass(options) {
// console.log(defaults)
if(typeof options === 'object') {
return _.extend(this, defaults, options);
}
else {
return _.extend(this, defaults);
}
}
return MyClass;
})();
var myObj = new MyClass({foo: 'bar'})
myObj.myArr.push('baz')
var mySecondObj = new MyClass();
console.log(mySecondObj) // MyClass {myArr: Array[1]}
我希望mySecondObj.myArr
是一个空数组。
当我将值推入myObj.myArr
,defaults.myArr
以某种方式被更改并用于后续的类实例时,该怎么办?
答案 0 :(得分:3)
将对象属性从defaults
合并到this
与_.extend
时,您只需创建对该数组的引用。因此,当更新一个实例中的数组引用时,所有引用都会反映该更改。
您可以克隆该对象以解决此问题:
_.cloneDeep(defaults)
或使用更简单的构造函数:
function MyClass(options) {
var defaults = {
myArr: [],
myProp: 'I\'m a default value'
}
if (typeof options === 'object') {
_.extend(this, defaults, options);
} else {
_.extend(this, defaults);
}
}
答案 1 :(得分:1)
简单说明:您创建了closure。
在自执行函数中创建另一个函数,您创建的函数从它的父自执行函数继承defaults
,当您将函数返回到MyClass
时,任何对象创建都将具有这些默认值(the defaults object
)的引用相同,每次创建类时都没有创建defaults
对象,这就是为什么它总是相同的。