原型(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.<strong>proto.</strong> proto 由上图可知: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"

prototype

访问person1的drink属性时,person1对象没有搜寻到则搜寻person1的原型Person.prototype,匹配到了drink属性。 valueOf .valueOf 方法是Object内置方法,由原型链可在Object中搜寻到。除了.valueOf 方法外Object还有很多内置方法

Note:

JavaScript Object Layout 这是一张很有名的图片关于Prototype的图

Function.__proto__ === Object.__proto__ //true

Reference:

【Just JavaScript #08】原型 Prototypes
Javascript 原型中的哲学思想 | BlueSun (huang-jerryc.com)
https://www.youtube.com/watch?v=iinGFJR6wsg