确定新对象和新fn之间的区别

时间:2009-07-25 17:13:06

标签: javascript prototype

在这些情况下,如何确定new Objectnew 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");

2 个答案:

答案 0 :(得分:3)

据我所知,使用ES3无法解决您的问题:instanceofisPrototypeOf()无法用于解决问题,因为fn的原型对象无法访问,并且只有ES5允许通过Object.getPrototypeOf()访问内部[[Prototype]]属性。

顺便说一句,如果你将Object.prototype分配给fn.prototype,那么要解决的问题更难解决,例如

var x = (function() {
    function Foo() {}
    Foo.prototype = Object.prototype;
    return new Foo;
})();

由于FooObject个实例的原型链是相同的,因此不应该有任何区别对象。

答案 1 :(得分:3)

我很确定你只能通过标准支持在ES3中做到这一点,这就是原因:

查看xy创建。

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