在这些情况下,如何确定new Object
和new fn
之间的差异?
var fn = function(){};
fn.prototype = {};
__proto__
或Object.getPrototypeOf
,因为它们不在IE或Opera中。fn
,例如instanceof fn
。Object.getPrototypeOf
很好。不是必需的:如果您的解决方案适用于其他帧中的对象并且不使用函数序列化,那将是很好的。
以下是一些示例基本代码:
var fn = function(){};
fn.prototype = {};
var x = new fn,
y = new Object;
fn = null; // prohibit static reference to fn
// define your detection function here
function isNewObject(obj) {
};
alert(isNewObject(x) !== isNewObject(y) ? "pass" : "fail");
答案 0 :(得分:3)
据我所知,使用ES3无法解决您的问题:instanceof
和isPrototypeOf()
无法用于解决问题,因为fn
的原型对象无法访问,并且只有ES5允许通过Object.getPrototypeOf()
访问内部[[Prototype]]属性。
顺便说一句,如果你将Object.prototype
分配给fn.prototype
,那么要解决的问题更难解决,例如
var x = (function() {
function Foo() {}
Foo.prototype = Object.prototype;
return new Foo;
})();
由于Foo
和Object
个实例的原型链是相同的,因此不应该有任何区别对象。
答案 1 :(得分:3)
我很确定你只能通过标准支持在ES3中做到这一点,这就是原因:
查看x
和y
创建。
var fn = function(){};
fn.prototype = {};
var x = new fn,
y = new Object;
当x
被实例化时,其内部[[Prototype]]被设置为fn.prototype
引用的对象(只是您分配给Object
的{{1}}个对象)。然后在新创建的对象的上下文中调用Object的构造函数 - fn.prototype
,但由于它不以任何方式改变ab对象,我们可以认为该步骤无关紧要。
当fn
被实例化时,其内部[[Prototype]]被设置为y
,这也是Object.prototype
对象。然后在这个新创建的对象的上下文中调用它的构造函数(Object
),但是也没有任何事情发生。
所以现在你最终得到2个Object
个对象,它们的内部[[Prototype]]引用了不同的对象 - Object
只引用了你赋予{{1}的任何对象}和x
的引用fn.prototype
。它们的内部[[Class]]属性也相同(即等于“Object”)
您无法直接访问ES3中的[[Prototype]]。您可以使用y
推断出有关它的内容,但由于Object.prototype
在您的示例instanceof
中已为空,因此基于推理是不可能的。
现在,您可以通过某种方式改变实例化对象来扩充fn
构造函数。然后,您可以检查对象并检测此增强。例如:
intanceof
然后:
Object
但是,这当然只有在使用Object = function() {
return ({ __: void 0 });
}
而不是通过对象文字 - function isNewObject(object) {
return '__' in object;
}
创建对象时才有效。它也相当突兀:)
也许还有其他方法,但我现在看不到它们。
HTH