JS-原型和原型链

在讲原型和原型链以前,咱们先来了解一下构造函数。浏览器

构造函数

构造函数自己就是一个函数,不过为了规范通常将其函数名的首字母大写。bash

构造函数和普通函数的区别在于,使用 new 生成实例的函数就是构造函数,直接调用的就是普通函数。函数

function Person(name) {
  this.name = name;
}
let person1 = new Person('xmm');
console.log('姓名:', person1.name);
//姓名: xmm
复制代码

在上面的代码中,Person就是构造函数,使用new建立了一个实例对象person1ui

代码

接下来我会根据一段代码和相应的图解来说述原型prototype和原型链__proto__的的区别和联系。this

//构造函数 Person
function Person(name) {
  this.name = name;
}
Person.sex = 'girl';
Person.prototype.age = 18 ;
console.log('Person.sex ',Person.sex);         //Person.sex  girl

// 构造函数的实例
let person1 = new Person('gxm');
let person2 = new Person('xmm');

console.log('person1.name:', person1.name);  //person1.name:gxm
console.log('person2.name:', person2.name);  //person2.name:xmm

//修改和自定义属性
person1.age = 20;
person2.loveAction = '指尖的跳跃';
console.log('person1.age:', person1.age);    //person1.age:20
console.log('person2.age:', person2.age);    //person2.age:18
console.log('person2.loveAction:', person2.loveAction);//person2.loveAction: 指尖的跳跃

console.log('person1.sex', person1.sex);      //person1.sex undefined
console.log('person2.sex', person2.sex);      //person1.sex undefined

console.log(person1.__proto__ === Person.prototype);  // true
console.log(person1.constructor === Person);          // true
console.log(Person.prototype.constructor === Person); // true
复制代码

图解:spa

原型 prototype

构造函数的原型prototype属性是一个指针,指向的是原型对象,关系以下:prototype

每一个函数都会有一个 prototype属性,这个属性是一个指针,指向原型对象(如图中的 Person .prototype),这个对象正是调用该构造函数而建立的实例的原型,也就是这个例子中的 person1person2 的原型。

记住只有函数才有,而且经过bind()绑定的也没有。3d

原型对象的好处是可让全部对象实例共享它所包含的属性和方法。指针

引伸:constuctor和原型对象的关系

如今理解原型对象(Person.prototype)下constructor属性code

这个constuctor属性其实就是将原型对象指向关联的构造函数。上述代码中的这两句输出语句能够说明。

console.log(person1.constructor === Person);          // true
console.log(Person.prototype.constructor === Person); // true
复制代码

实例 person1person2能够经过__proto__来访问构造函数的原型对象。就是咱们接下来要讲的__proto__属性。

原型链 __proto__

其实每一个JS对象都有__ proto __属性,这个属性指向了原型。这个属性在如今来讲已经不推荐直接去使用了,这只是浏览器在早期为了让咱们访问到内部属性[[prototype]]来实现的一个东西。

person1person2实例对象下面有一个[[prototype]]属性,其实没有标准的方式能够访问它,可是主流浏览器上在每一个对象上 (null除外) 都支持一个属性,那就是__ proto __,这个属性会指向该对象的原型。

因此总结可得__ proto __就是用来将 实例对象该实例对象的原型相连

综上所述:

prototype是构造函数访问原型对象,_ proto _是对象实例访问原型对象。

补充:

  • Object 是全部对象的爸爸,全部对象均可以经过 __proto__ 找到Object.prototype,在经过Object.prototype.constructor找到它
  • Function 是全部函数的爸爸,全部函数均可以经过 __proto__ 找到Function.prototype,在经过Function.prototype.constructor找到它
  • 函数的 prototype 是一个对象
  • 对象的__proto__属性指向原型,__proto__将对象和原型链接起来组成了原型链