我正在试图弄清楚是否有方法可以判断对象是使用Object.create()
还是使用new
关键字/文字语法创建的。因为使用Object.create()
创建的对象不会从prototype属性中获取属性(它们只是复制所有属性),而使用new
和文字语法创建的对象仅使用prototype属性中的属性,似乎很难说出对象是如何创建的。例如:
function Meat() {};
var beef = new Meat();
var tuna = Object.create(Meat);
console.log(Object.getPrototypeOf(tuna));//=> [Function: Meat]
console.log(Object.getPrototypeOf(beef));//=> {}
console.log(tuna.constructor.prototype);//=> [Function]
console.log(beef.constructor.prototype);//=> {}
console.log(tuna.prototype);//=> {}
console.log(beef.prototype);//=> undefined
console.log(tuna.__proto__);//=> object
console.log(beef.__proto__);//=> object
console.log(typeof tuna);//=> object
console.log(typeof beef);//=> object
console.log(Meat.prototype.isPrototypeOf(tuna));//=> false
console.log(Meat.prototype.isPrototypeOf(beef));//=> true
似乎没有办法告诉对象继承它的属性的方法。有什么想法吗?
答案 0 :(得分:1)
Object.create
是一种非常通用的对象构造操作。 没有办法告诉对象是否是使用Object.create
创建的,因为这些对象没有可靠的功能(除此之外他们无法做到)本机对象或代理)。
根本不是Object.create
只是复制所有属性“ - 它只是将[[Prototype]]
(又名__proto__
)引用设置为您提供的值。唯一类似“复制”的行为是指定可选的第二个参数,但它采用属性描述符。
我注意到你犯了一个错误,可能会让你混淆这个问题:
var tuna = Object.create(Meat);
如果您的意思是“制作一个类似于new Meat()
”结果的对象,那么这是错误的。你想要的是:
var tuna = Object.create(Meat.prototype);
因为Object.create
的参数是新对象的原型,而不是构造函数。通过执行此操作获得的对象将对instanceof
,isPrototypeOf
等作为new Meat()
作出相同的反应;它只是没有在其上运行Meat
构造函数,因此它不会拥有此类对象通常所做的任何属性。
由于您的示例构造函数为空,一旦您解决了这个问题,这两个对象将对您的各种测试产生相同的响应。这并不能帮助你区分(因为你不能),但它应该可以帮助你不需要分辨出来。
答案 1 :(得分:0)
无法可靠地确定对象是否是使用Object.create或new someFunction语法创建的。对象的constructor
属性是最有用的指南,但不保证结果。例如:
function Foo() {};
var foo = new Foo();
foo.constructor == Foo; // true
但constructor
不是只读属性,所以
Foo.prototype.constructor = Object;
foo.constructor == Foo; // changes to false
完整地设置构造函数的原型对象通常也会将构造函数(由实际构造函数创建的对象继承)更改为原型的构造函数:
Foo.prototype = {foo: "was here"};
var foo = new Foo ();
foo.constructor == Foo; // false
foo.constructor == Object; // true, the constructor of {foo: "was here"} is Object.
最后一个结果,foo
的原型链结构现在与Object.create创建的结构相同:
var foo = Object.create({foo: "was here"};
foo.constructor == Object; // true;
但为了突破这个有用的希望,Object.create()返回对象的构造函数不必是Object:
var bar = Object.create( new Foo()); // the original Foo
bar.constructor == Object ; // false
bar.constructor == Foo; // true;
或多或少的任何组合"关键属性"可以使用构造函数或 Object.create进行设置。某些组合可能是人为的,但其他组合将是设计或易于编码。
Object.create
不会通过设计在原型链中留下可检测到的面包屑。