gpt4 book ai didi

javascript - 在 javascript 中创建和扩展对象会覆盖基础对象的变量

转载 作者:行者123 更新时间:2023-11-30 17:41:06 25 4
gpt4 key购买 nike

我有一个基本的 Object.create 包装器用于我们的应用程序。基本上,该过程是在父对象上使用 Object.create,然后使用 .extend({}) 向其添加新功能。如果我们需要调用父类的方法,我们只需在方法覆盖中使用 ParentClass.myFunc.apply(this, arguments);。我遇到的问题是当我初始化一个对象并调用父对象的 init 函数时,它会覆盖父对象的属性。我怎样才能防止这种情况发生?

这是主要的 Object.create 包装器:

/**
* Simple wrapper for Object.create and Object.extend
* functionality.
*/
var My_Object = {
/**
* Simple extend function for inheritance
* @param props An object of functions to place in the new object.
* @returns {My_Object}
*/
extend: function(props) {
for(var prop in props)
this[prop] = props[prop];

return this;
},

/**
* Basic function that checks if a function is native or user-created
* @author Yong (http://stackoverflow.com/users/962254/yong)
*
* @param f The function to test if it is native
* @returns {boolean}
*
* @see http://stackoverflow.com/questions/6598945/detect-if-function-is-native-to-browser
*/
isFuncNative: function(f) {
return !!f && (typeof f).toLowerCase() == 'function'
&& (f === Function.prototype
|| /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
},


/**
* Simple polyfill wrapper for native Object.create. Using a polyfill
* instead of native incase for some reason consumer would have overwritten
* it with unexpected usage.
*/
create: function(obj) {
// If the browser supports Object.create and hasn't been overwritten,
// use the native version instead of the polyfill
if(My_Object.isFuncNative(Object.create)) {
// If extend hasn't been defined, add it
if(!obj.hasOwnProperty('extend'))
obj.extend = My_Object.extend;

return Object.create(obj);
}


// Create empty function for polyfill
function F(){}
F.prototype = o;

// If extend hasn't been defined, add it
if(!F.prototype.extend)
F.prototype.extend = My_Object.extend;

return new F()
}
};

然后我定义一个基础对象:

var SomeParentObject = {
options: {
a: 'a',
b: 'b'
},

init: function(options) {
this.options = $.extend(this.options, options || {});

return this;
}
};

有些 child 反对:

var ChildObject1 = My_Object.create(SomeParentObject).extend({
init: function() {
SomeParentObject.init.call(this, {b: 'c'});

return this;
}
}).init();

var ChildObject2 = My_Object.create(SomeParentObject).extend({}).init();

现在期望的结果是永远不要修改SomeParentObject 的选项。我无法弄清楚到底是什么原因造成的,但我确定这是我在做的愚蠢的事情。如果您执行一些基本的 console.log,您会看到当 ChildObject2 有一些要覆盖的选项时,它会为 SomeParentObject 覆盖它,并且因此对于所有的 child 。

console.log('<<SomeParentObject.a, SomeParentObject.b>>');
console.log(SomeParentObject.options.a + ', ' + SomeParentObject.options.b);

console.log('<<ChildObject1.a, ChildeObject1.b>>');
console.log(ChildObject1.options.a + ', ' + ChildObject1.options.b);

console.log('<<ChildObject2.a, ChildeObject2.b>>');
console.log(ChildObject2.options.a + ', ' + ChildObject2.options.b);

哪些输出:

<<SomeParentObject.a, SomeParentObject.b>>
a, c
<<ChildObject1.a, ChildeObject1.b>>
a, c
<<ChildObject2.a, ChildeObject2.b>>
a, c

应该输出的是这样的:

<<SomeParentObject.a, SomeParentObject.b>>
a, b
<<ChildObject1.a, ChildeObject1.b>>
a, c
<<ChildObject2.a, ChildeObject2.b>>
a, b

最佳答案

如果您不喜欢 JavaScript 中原型(prototype)设计的工作方式以实现简单的继承和 OOP 方式,我建议您看一看:https://github.com/haroldiedema/joii

它基本上允许您执行以下(以及更多)操作:

// First (bottom level)
var Person = new Class(function() {
this.name = "Unknown Person";
});

// Employee, extend on Person & apply the Role property.
var Employee = new Class({ extends: Person }, function() {
this.name = 'Unknown Employee';
this.role = 'Employee';

this.getValue = function() {
return "Hello World";
}
});

// 3rd level, extend on Employee. Modify existing properties.
var Manager = new Class({ extends: Employee }, function() {

// Overwrite the value of 'role'.
this.role = this.role + ': Manager';

// Class constructor to apply the given 'name' value.
this.__construct = function(name) {
this.name = name;
}

// Parent inheritance & override
this.getValue = function() {
return this.parent.getValue().toUpperCase();
}
});

// And to use the final result:
var myManager = new Manager("John Smith");
console.log( myManager.name ); // John Smith
console.log( myManager.role ); // Manager

console.log( myManager.getValue() ); // HELLO WORLD

关于javascript - 在 javascript 中创建和扩展对象会覆盖基础对象的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com