在JavaScript中,prototype
属性和__proto__
属性(通常读作"proto")是有关于对象原型链的概念,但它们在使用和目的上有所不同。
prototype
属性
prototype
是函数对象(Function objects)的一个属性。当你使用构造函数创建一个新对象时,这个新对象的内部[[Prototype]]
(也就是它的__proto__
属性)会被赋值为构造函数的prototype
属性。这意味着,使用同一个构造函数创建的所有对象都会共享同一个prototype
对象。
举个例子,如果我们有一个构造函数:
javascriptfunction Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); };
当我们创建一个Person
实例时:
javascriptvar person1 = new Person("Alice");
person1
对象的[[Prototype]]
(即__proto__
)会指向Person.prototype
,这使得person1
能够访问到sayHello
方法。
__proto__
属性
__proto__
是每个JavaScript对象都拥有的一个内部属性,它指向该对象的原型。这是一个从对象指向其构造函数的prototype
属性的链接。根据ECMAScript标准,__proto__
是[[Prototype]]
的实现,而[[Prototype]]
是对象的内部属性。在现代JavaScript开发中,通常推荐使用Object.getPrototypeOf(obj)
来获取对象的原型,而不是直接使用__proto__
,因为__proto__
并不是所有JavaScript环境中都得到支持。
再次拿刚才的例子,person1.__proto__
会指向Person.prototype
,因为person1
是由Person
构造函数创建的。
小结
prototype
是函数特有的属性,用于当作构造函数时为实例对象指定原型。__proto__
是每个对象都有的属性,指向该对象的原型。
在实践中,prototype
用来实现基于原型的继承和共享属性/方法,而__proto__
提供了一种访问和操作对象原型链的方式。然而,直接操作__proto__
被视为不太安全的做法,尤其是在现代JavaScript编程中,应该利用Object.getPrototypeOf()
和Object.setPrototypeOf()
等方法来替代__proto__
的直接使用。