Javascript克隆对象失去了原型函数 [英] Javascript cloned object looses its prototype functions
问题描述
我试图在Javascript中克隆一个对象。我创建了自己的类,它具有原型函数。
I am attempting to clone an object in Javascript. I have made my own 'class' that has prototype functions.
我的问题:当我克隆一个对象时,克隆无法访问/调用任何原型函数。
My Problem: When I clone an object, the clone cant access/call any prototype functions.
当我去访问克隆的原型函数时出现错误:
I get an error when I go to access a prototype function of the clone:
clone.render不是函数
clone.render is not a function
你能告诉我如何克隆一个对象并保留其原型函数
这个简单的JSFiddle演示了我得到的错误: http://jsfiddle.net/VHEFb/1/
This simple JSFiddle demonstrates the error I get: http://jsfiddle.net/VHEFb/1/
function cloneObject(obj)
{
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
var copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
var copy = [];
for (var i = 0, len = obj.length; i < len; ++i) {
copy[i] = cloneObject(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = cloneObject(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
function MyObject(name)
{
this.name = name;
// I have arrays stored in this object also so a simple cloneNode(true) call wont copy those
// thus the need for the function cloneObject();
}
MyObject.prototype.render = function()
{
alert("Render executing: "+this.name);
}
var base = new MyObject("base");
var clone = cloneObject(base);
clone.name = "clone";
base.render();
clone.render(); // Error here: "clone.render is not a function"
推荐答案
对代码的一些评论:
> if (obj instanceof Date) {
> var copy = new Date();
> copy.setTime(obj.getTime());
可以是:
if (obj instanceof Date) {
var copy = new Date(obj);
和
> if (obj instanceof Array) {
如果obj是来自另一个全局上下文的数组,则返回false,例如作为iFrame。考虑:
will return false if obj is an array from another global context, such as an iFrame. Consider:
if (o && !(o.constructor.toString().indexOf("Array") == -1))
> var copy = [];
> for (var i = 0, len = obj.length; i < len; ++i) {
> copy[i] = cloneObject(obj[i]);
> }
使用<$ c $可以更有效,更准确地将一个数组的索引复制到另一个数组c> slice :
var copy = obj.slice();
虽然你会遗漏任何其他可能已添加的非数字属性。循环超过0到将为克隆添加稀疏数组中不存在的属性(例如,精简将成为未定义的成员)。
though you will miss any other properties that might have been added that aren't numeric. Looping over 0 to length will add properties to the clone that don't exist in a sparse array (e.g. elisions will become undefined members).
至于克隆部分...
在零件复制对象属性中,将复制所有属性,包括原始 [[Prototype]] $ c $上的属性c> chain,直接到clone对象。真正克隆对象的唯一方法是将
[[Prototype]]
设置为与原始对象相同的对象,然后复制原始的可枚举属性(已过滤使用 hasOwnProperty
)克隆。
In the part copying object properties, that will copy all the properties, including those on the original's [[Prototype]]
chain, directly to the "clone" object. The only way to really "clone" an object is to set its [[Prototype]]
to the same object as the original, then copy the enumerable properties on the original (filtered with hasOwnProperty
) to the clone.
第二部分是微不足道的,第一部分不是(在一般意义上),因为你无法保证对象的构造函数属性引用其<$ c的对象$ c> prototype 是它的 [[Prototype]]
,也不能保证构造函数的原型没有改变(即是一个不同的对象)在此期间。
The second part is trivial, the first part is not (in a general sense) since you can't guarantee that an object's constructor property references the object whose prototype
is its [[Prototype]]
, nor can you guarantee that the constructor's prototype hasn't changed (i.e. is a different object) in the meantime.
您最接近的是使用 Lasse Reichstein Nielsen的克隆
(由Douglas Crockford推广为 beget
)使原始对象成为克隆的 [[Prototype]]
,然后将构造函数设置为同一对象。虽然您可能仍需要复制可枚举的自有属性,因此它们会掩盖原始的同名属性。
The closest you can get is to use Lasse Reichstein Nielsen's clone
(popularised by Douglas Crockford as beget
) which makes the original object the [[Prototype]]
of the clone, and then set the constructor to the same object. Though you probably still need to copy over the enumerable own properties so they mask the original's same-named properties.
因此,您实际上只能在受限制的上下文中克隆对象,你一般不能这样做。通常,这种实现会导致您无需一般性地克隆对象的设计。
So you can really only clone an object within a restricted context, you can't do it generally. And generally that realisation leads to a design where you don't need to generically clone objects.
这篇关于Javascript克隆对象失去了原型函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!