当我在Chrome控制台中输入Object.prototype
时,会显示Object{}
如果我将其分配给变量var proto = Object.prototype
,则会显示Object{}
但如果我检查它的原型
var proto = Object.prototype
proto.prototype;
如果proto
是Object{}
且proto.prototype
未定义,则表示Object()
是Object()
从任何东西继承?
此外,这是否与Object.prototype.prototype
相同?
答案 0 :(得分:4)
如果 Object 具有原型,则原型也是 Object 。这些对象全部链接在一起,直到您到达 null ,这是原型链的结尾。
yield from
但是,您还应注意,您无法继续访问// Object is a constructor
Object.prototype; // Object {}, will be the prototype of `new Object`s
// Object.prototype is an Object
Object.getPrototypeOf(Object.prototype); // null, we are at the end of the chain
属性,因为这仅适用于构造函数,请考虑
obj.prototype
找到 Object 原型的正确方法是使用function Foo() {
}
Foo.prototype; // Foo {}
// vs
(new Foo).prototype; // undefined
,
Object.getPrototypeOf(obj)
还可能会注意到旧版浏览器可能不支持Object.getPrototypeOf(new Foo) === Foo.prototype; // true
,在这种情况下,许多浏览器会提供属性Object.getPrototypeOf
。但是,如果您需要访问原型链,请尽量避免在此类浏览器的垫片外使用obj.__proto__
。
最后,将__proto__
与构造函数一起使用并不是创建此链的唯一方法,您可以使用new
Object.create
还要考虑
var a = Object.create(null),
b = Object.create(a), // b will inherit from a
c = Object.create(b); // c will inherit from b, hence also a
a.foo = 'foo';
b.bar = 'bar';
a instanceof Object; // false
a.bar; // undefined
c.foo + c.bar === 'foobar'; // true
答案 1 :(得分:3)
Object.prototype
是您可以进入原型链的最远的地方。
它Object.prototype
没有原型属性,所以你看到的是undefined
。实际上,它的原型是null
。您可以使用Object.getPrototypeOf
方法或__proto__
属性确认。
Object.getPrototypeOf(Object.prototype); // null
Object.prototype.__proto__; // null
prototype
属性不是遍历原型链的可靠方法,因为在许多情况下,它不存在。
function MyObj() {}
MyObj.prototype.a = 3;
(new MyObj).prototype; // undefined
Object.create({ a: 3 }).prototype; // undefined
__proto__
property不是标准,可能会从ES的未来版本中删除。但在兼容的浏览器中,它将以预期的方式工作。
Object.create({ a: 3 }).__proto__; // Object {a: 3}
答案 2 :(得分:1)
关于原型可以说很多,但下面的简要说明可以帮助澄清主题,使其更容易理解:
A)prototype
是函数的属性。
Object.constructor
会返回function Function() { [native code] }
,因此我们可以获取prototype
,就像您能够获得prototype
Object
本身一样。这是因为它是一个功能。 typeof Object
返回"function"
。另一方面,typeof Object.prototype
会返回"object"
,因此您无法获得Object.prototype
的原型。
// get prototype property of a function
var hello = function () {};
hello.prototype // hello {}
// get prototype property of an object
typeof hello.prototype // "object"
hello.prototype.prototype // undefined
hello = {};
hello.prototype // undefined
我们可以使用Constructor
属性向prototype
(这是一个函数)添加属性和方法。
function Hello() {}
Hello.prototype.print = function () { console.log('hello'); };
// not using a constructor
var hello = Hello(); // undefined
hello.print(); // ERROR
// using a constructor
hello = new Hello(); // Hello {print: function}
hello.print(); // "hello"
B)__proto__
是所有对象(包括函数)的属性。
请注意,Object.__proto__
相当于Object.constructor.prototype
和Object.getPrototype(Object)
。
prototype
没有Object.prototype
属性,因为它不是函数。但因为它是一个对象,我们可以Object.prototype.__proto__
返回null
。获得null
意味着我们处于原型链的末端。
甚至函数都有__proto__
:
function Hello() {}
Hello.__proto__ // function Empty() {}
__proto__
是JS引擎用于继承/委托链接的内部原型。
function Hello() {}
var hello = new Hello();
hello.__proto__ === Hello.prototype // true