阅读 9

JS-原型和原型链

在讲原型和原型链之前,我们先来了解一下构造函数。

构造函数

构造函数本身就是一个函数,不过为了规范一般将其函数名的首字母大写。

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

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

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

代码

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

//构造函数 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
复制代码

图解:

原型 prototype

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

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

记住只有函数才有,并且通过bind()绑定的也没有。

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

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

现在理解原型对象(Person.prototype)下constructor属性

这个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__将对象和原型连接起来组成了原型链
关注下面的标签,发现更多相似文章
评论