原型(prototype) && 原型指针(proto)
原型指针和原型
原型指针: __proto__
__proto__
浏览器中显示为[[prototype]]
JavaScript当中每个对象都有一个特殊的内置属性[[prototype]],这个特殊的对象可以指向另外一个对象。这个属性在现在来说已经不推荐直接去使用它了,这只是浏览器在早期为了让我们访问到内部属性 [[prototype]] 来实现的一个东西。
原型:prototype
每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
prototype
不是一个函数对象的原型。它只是一个用new
关键字构造一个新的
对象的原型。
new操作符的执行过程
- 创建一个空的对象
- 对象的__proto__ = 构造函数的 prototype
function Person(name, age) {
this.name = name;
this.age = age;
}
// 通过Person构造函数创造出了对象 person1
const person1 = new Person("Lily", 19);
const person2 = new Person("Alice", 22);
person1.__proto__ === person2.__proto__ // true
// 对象person1 的__proto__ = 构造函数Person的 prototype
person1.__proto__ === Person.prototype // true
由上图可知:person1.__proto__ === Object
person1.__proto__.__proto__ === Object.prototype // true
constructor属性
- 默认情况下原型上都会有一个属性叫做constructor,constructor指向当前的函数对象本身
- 每创建一个函数, 就会同时创建它的prototype对象, 这个对象也会自动获取constructor属性
function Person(){}
var p1 = new Person();
console.log(Person.prototype.constructor === Person) // true
console.log(p1.__proto__.constructor) // [Function: Person]
console.log(p1.__proto__.constructor.name) // Person
// 因为是循环引用
console.log(p1.__proto__.constructor === Person.prototype.constructor)
console.log(Person.prototype === Person.prototype.constructor.prototype)
原型链(prototype chain)
JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不在该对象上搜寻 不到时,就会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾, 即最顶层null
原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。
当你构造了一个对象,__proto__
是为了在peototype chain上寻找某一方法.
Person.prototype.drink = "cola"
访问person1的drink属性时,person1对象没有搜寻到则搜寻person1的原型Person.prototype,匹配到了drink属性。 .valueOf 方法是Object内置方法,由原型链可在Object中搜寻到。除了.valueOf 方法外Object还有很多内置方法
Note:
这是一张很有名的图片关于Prototype的图
Function.__proto__ === Object.__proto__ //true
Reference:
【Just JavaScript #08】原型 Prototypes
Javascript 原型中的哲学思想 | BlueSun (huang-jerryc.com)
https://www.youtube.com/watch?v=iinGFJR6wsg