I have some test class
TestKlass = (function() {
function TestKlass(value) {
this.value = value != null ? value : 'hello world';
console.log(this.value);
}
return TestKlass;
})();
x = new TestKlass;
x instanceof TestKlass; (gives true)
I have new empty object
y = {}
y instanceof Object
Can I find any ways to set any properties for y, something like this
y.__proto__ = x.__proto__
y.constructor.prototype = x.constructor.prototype
for to have this result
y instanceof TestKlass => true
====================================================
UPD:
So. My main aim – it’s to create CLONE function. Now my solution works for me. Please look at this code:
JavaScript JS object clone
Object._clone = function(obj) {
var clone, property, value;
if (!obj || typeof obj !== 'object') {
return obj;
}
clone = typeof obj.pop === 'function' ? [] : {};
clone.__proto__ = obj.__proto__;
for (property in obj) {
if (obj.hasOwnProperty(property)) {
value = obj.property;
if (value && typeof value === 'object') {
clone[property] = Object._clone(value);
} else {
clone[property] = obj[property];
}
}
}
return clone;
};
CoffeeScript JS object clone
# Object clone
Object._clone = (obj) ->
return obj if not obj or typeof(obj) isnt 'object'
clone = if typeof(obj.pop) is 'function' then [] else {}
# deprecated, but need for instanceof method
clone.__proto__ = obj.__proto__
for property of obj
if obj.hasOwnProperty property
# clone properties
value = obj.property
if value and typeof(value) is 'object'
clone[property] = Object._clone(value)
else
clone[property] = obj[property]
clone
Now you can try to do that
A = new TestKlass
B = Object._clone(A)
B instanceof TestKlass => true
It’s work fine with Moz FF 13. But I think it’s not cross-browser. and proto is deprecated.
I think there is no universal solution. But maybe It’s will be helpful for somebody.
Perhaps you should read the following answer first. What you are trying to achieve is really simple. However before I explain let’s look at your solutions:
Solution 1
I wouldn’t recommend doing this as the
__proto__property is now deprecated. The above code won’t work in Rhino.Solution 2
This is a very bad solution. The reason is that
y.constructoris actuallyy.__proto__.constructorand sinceyis an objecty.__proto__is the same asObject.prototype. This means thaty.constructoris the same asObjectand you’re essentially changing theprototypeproperty ofObject. This could potentially break other code on your page. I strongly discourage this practice.Solution 3 (my solution)
What you want to do is simply change the internal
[[proto]]property of an object. Since there’s no cross platform way to do so we need to employ a hack. A simple solution would be to create a new object with the desired__proto__property and set getters and setters on it to change the original object. It would be as follows:After this all you need to do is:
Here is a working fiddle.
Edit:
The problem with your clone function is that it only clones objects and arrays. You forgot to account for functions which are also passed by reference. Thus when you clone an object which has methods which close over the internal state of the object, the object and its clone will share the same internal state. See the following fiddle:
There’s absolutely no way in JavaScript to clone the internal state of an object so cloning objects and arrays in JavaScript will only work for objects which do not expose closures as methods.
To know more about the problems with cloning objects in JavaScript read this answer. Click on the following link to read John Resig’s answer.