我知道再次阅读这个话题真的很烦人。在开始挖掘代码之前,一个解决方案可能是我没有在JavaScript中获得原型和对象。但在这一点上,我认为,我做到了。
问题是:
如何克隆JavaScript类(使用原型创建),以便“克隆”类在以后扩展和执行时保持不变?
function clone(obj){
if(obj == null || typeof(obj) != 'object')
return obj;
var temp = new obj.constructor();
for(var key in obj)
temp[key] = clone(obj[key]);
return temp;
}
var FOO = function() {
var myBAR = clone(BAR);
myBAR.prototype = jQuery.extend(true, myBAR.prototype, this); // deep cloning twice and extending with this
console.log("FOO:", this.name);
new myBAR();
};
FOO.prototype = {
name: "FOO"
};
var BAR = function() {
console.log("BAR:", this.name);
};
BAR.prototype = {
name: "BAR"
};
new FOO(); // returns FOO: FOO and BAR: FOO
new BAR(); // returns BAR: FOO should return BAR: BAR
如果我说对了,new BAR()
(new FOO()
之后)的第二次调用应该返回BAR: BAR
而不是BAR: FOO
。
此问题的一个可能解决方案是完全重写clone
函数,如下所示:
function clone(obj) {
return eval("("+obj.toString()+")"); // the same as eval(uneval(obj));
}
但是这种方法有一个很大的缺点,你不能传递任何动态创建的对象。
有什么想法吗?
答案 0 :(得分:1)
问题是你如何克隆'原型'
以下一行
myBAR.prototype = jQuery.extend(true, myBAR.prototype, this); // deep cloning
您不仅要克隆'原型',还要克隆'name'属性。
如果用
替换上面的行myBAR.prototype = jQuery.extend(true, myBAR.prototype, this.prototype); // deep cloning
您的代码现在将返回
new FOO(); // returns FOO:FOO and BAR:BAR
new BAR(); // returns BAR:BAR
答案 1 :(得分:0)
克隆javascript对象的问题是你决定去多深?
考虑我有以下对象:
var obj = {
prop : {
n1prop : {
hello : 'world';
}
}
};
这意味着我必须遍历所有属于'object'类型的属性,如果你有一个深层嵌套可能会非常昂贵。
如果你有一个简单的1级对象,你可以使用简单的反射循环并创建一个新的对象文字。 注意:这不会复制原始对象的方法。
function clone(obj) {
var cloned;
if (obj && typeof obj === 'object') {
cloned = {};
for (var p in obj) {
if (obj.hasOwnProperty(p) && typeof obj[p] !== 'function') {
cloned[p] = obj[p]
}
}
return cloned;
}
else {
return null;
}
}
答案 2 :(得分:0)
除了SolutionYogi提到的更改之外,还需要进行另一项更改。在FOO中,你要传递要克隆的BAR,但是BAR是构造函数(typeof BAR ==“function”),所以它将使第一次测试克隆函数失败,并且你的返回值将是对未更改的BAR的引用。这意味着myBAR.prototype不是BAR.prototype的克隆,而是对它的引用。
为了实际创建一个新的构造函数,而不仅仅是一个ref,我认为你将不得不使用eval - 添加如下内容:
if (typeof obj == "function) {
eval("var temp = " + obj + ";");
return temp;
}
还有其他注意事项(正如Alex指出的那样),但添加上述内容会导致测试用例成功。
答案 3 :(得分:0)
function clone(obj) {
if(typeof obj !== 'undefined') {
clone.prototype = Object(obj);
return new clone;
}
}
function Foo() {} // base class
function Bar() {} // derived class
Bar.prototype = clone(Foo.prototype); // inherit from `Foo.prototype`
答案 4 :(得分:0)
我只想向任何人展示我上述问题的解决方案。
function cloneClass (func) {
if(typeof func == 'function') {
var prototype = {};
for (var prop in func.prototype) {
prototype[prop] = func.prototype[prop];
};
var Class = function() {
var _this = this;
var constructor = function() {
func.apply(_this, arguments);
};
constructor.prototype = _this;
for (var property in func) {
if(property != "prototype") {
constructor[property] = func[property];
}
};
return constructor;
};
Class.prototype = prototype;
return new Class();
}
return func;
};
尝试深入了解它是如何工作的。有没有人能看到这个实现,内存泄漏等问题。