原型和原型链

176 阅读3分钟

1.原型

Js的原型和原型链是:
1、原型模式是用于创建重复的对象,同时又能保证性能,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式;
2、原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找

1.prototype

我们知道在JS中每次创建一个函数,该函数就会自动带有一个prototype属性,该属性指向函数的原型对象。

function Person(age) {
    this.age = age       
}
Person.prototype.name = 'qiyue'//原型增加一个name属性
console.log(Person.prototype) //输出原型对象 {name: 'qiyue', constructor: ƒ}
var person1 = new Person()
var person2 = new Person()
console.log(person1.name) //qiyue 共享原型属性
console.log(person2.name)  //qiyue 共享原型属性

在这个例子中,prototype指向了一个对象,这个对象正是调用函数和创建实例的原型,也就是person1和person2的原型
原型的概念:每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。
接下来用一张图片来解释一下原型 850375-20190708151024134-512558007.png

2.proto

这是每个JS对象(null和undefined)都会有的属性,这个属性指向对象的原型

function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

关系图如下: 2.png
看着上面这张图,让我们来总结下:

  1. 构造函数(Person)通过prototype属性指向实例的原型。
  2. person是基于原型Person.prototype创建出的实例,并且可以通过__proto__属性指向其原型。
  3. Person.prototype和person.__proto__都指向实例的原型。

2.原型链

在JavaScript 中,每个对象通过__proto__属性指向它的原型对象,这个原型对象又有自己的原型,直到某个对象的原型为 null 为止,这种一级一级的链结构就称为原型链。

function Person(age){
  this.age = age
}
Person.prototype.name = 'qiyue'
var person = new Person();
console.log(person.__proto__);//Person.prototype=> {name: 'qiyue', constructor: ƒ}
console.log(person.__proto__.__proto__);//Object.prototype=>{constructor: ƒ,…}
console.log(person.__proto__.__proto__.__proto__);//null

当你用构造函数(Person)建立一个对象时,它的原型链就是: person ==》 Person.prototype ==》 Object.prototype ==》 null
再来看下对象属性的搜索

Person.prototype = {age:24};
var person = new Person("qiyue");
console.log(person.name);//qiyue
console.log(person.age);//24

对象属性的搜索是作用于整条原型链上的。搜索会从原型链头开始,直到原型链的末端,寻找这个属性,这个例子中name属性就在对象本身找到的(person),而age是在原型中找到的(Person.prototype)。

3.运用

instanceOf

function instanceOf(left, right)
{
    if (typeof left !== 'object' || left === null) return false;
    let proto = Object.getPrototypeOf(left);
    while (true)
    {   //循环往下寻找,直到找到相同的原型对象
        if (proto === null) return false;
        if (proto === right.prototype) return true;//找到相同原型对象,返回true
        proto = Object.getPrototypeOf(proto);
    }
}
console.log(instanceOf(person,Person));//true
console.log(instanceOf(person,Object));//true
console.log(instanceOf(person,Array));//false

instanceOf原理就是寻找构造函数的原型(prototype)是否在这个对象的原型链上。

扩展原型方法

var nums = new Array(1,2,3);
/**添加一个返回数组的第一个元素的新方法。 */
Array.prototype.first = function ()
{
    return this[0];
}
console.log(nums.first());//1

转载:(zhuanlan.zhihu.com/p/358006336)