深入解析原型&原型链

421 阅读3分钟

概念

原型链:每个实例对象都有一个私有属性__proto__指向实例的构造函数的原型对象(prototype),该原型对象也有自己的原型对象(proto),层层向上,直到原型对象是null为止,这种链型结构称为原型链 原型:每一个javascript对象创建的时候都会有一个与之关联的对象,这个对象就是原型,创建的对象从原型中继承方法和属性

首先我们先用一个构造函数创建一个实例对象 首先我们先说说什么是构造函数,其实构造函数和普通函数在创建上没有任何区别,只不过调用方式不一样而已,而且构造函数大部分使用大写字母开头,举个例子

function Demo(){}
const D = new Demo()

function demo(){}
const d = demo()
function Demo(){
	this.name = 'xx'
}
const demo = new Demo()
console.log(demo.name) // xx

这个例子Demo就是构造函数,demo就是实例 ​

prototype

每一个函数都会有一个prototype,并指向其实例对象的原型,那什么是原型呢? 每一个javascript对象创建的时候都会有一个与之关联的对象,该对象就是原型,创建的对象从原型中继承方法和属性,我们来看一个例子

function Demo(){	
}
Demo.prototype.name = 'xx'
const demo = new Demo()
const demo1 = new Demo()
demo.name === demo1.name // true

demo和demo1都是Demo的实例,Demo.prototype指向实例对象的原型,也就是上述例子中的demo,demo1的原型 image.png 那么怎么关联实例和原型之间的关系呢?

proto

简单来说每一个对象都有一个私有属性__proto__指向原型 我们可以用例子来确定一下这个观念

Demo.prototype === demo.__proto__ // true

所以上述的图可以更新为 image.png

constructor

知道了实例和实例原型,构造函数和实例原型的关系,那么构造函数和实例原型之间存在什么样的关系呢? 实例原型有一个constructor属性指向构造函数,我们可以用一段代码验证一下

Demo === Demo.prototype.constructor // true

所以上图又可以更新为 image.png 那么构造函数有没有什么属性可以指向实例呢? 答案是没有,因为一个构造函数可以创建多个实例 ​

原型链

之前我们也说过,原型是一个对象,对象都可以通过new Object()去创建,所以可以理解为实例原型就是继承自Object,写个例子验证一下

Demo.prototype.__proto__ === Object.prototype // true

所以可以把上图修改为 image.png 到了这一步,应该会想到,那么Object.prototype的原型又是什么呢?

Object.prototype.__proto__ // null

文章再开头就提到原型链的概念就是通过原型对象层层向上,直到null为止,所以上图就可以补充完成啦 image.png 上图中蓝色部分就是原型链 在网上看了一张原型关系的图,非常易于理解,贴在下方 image.png

instanceof

上面我们说了构造函数,原型和原型链的概念,接下来看看如何实现一个instanceof运算符 说一下实现的概念,一句话形容就是右边变量的原型在左边变量的原型链上即可

function myInstanceof(left, right) {
	const rightProto = right.prototype
  let leftProto = left.__proto__
  while(leftProto !== null) {
  	if (leftProto === rightProto) {
    	return true
      break
    }
    leftProto = leftProto.__proto__
  }
  return false
}

举个例子

function demo(){}
myInstanceof(demo, Object) // true

首先demo.__proto__等于Function.prototype,Function.prototype.__proto__等于Object.prototype,Object的原型就是Object.prototype所以返回true

原作链接:github.com/mqyqingfeng…