j这段时间参与到很多的笔试机会,大部分都考察到对原型上的理解和使用。
现对该知识进行一定的总结和回想。
原型与原型链
存在的以下的规则:
- 每一个构造器(一般为函数)都有
prototype
指向他的原型对象 - 每一个原型对象都有
construtor
指向他的构造器 - 由构造器创建的对象都有
__proto__
指向原型对象 - 最高层的原型对象的
__proto__
指向null
简单来说就如图所示:
代码解释:
function Person() { /* 构造器 */ } Person.prototype.constructor === Persion() // true const person = new Person() // 初始化一个实例 person.__proto__ === Persion.prototype // true (实例的__proto__ 与 构造器都是指向同一个原型对象的
更高层的原型链
运用场景:
原型与原型链主要的运用场景是:当我们使用实例的某个方法或是属性时,会发现本身该实例上并没有绑定相对应的方法或属性,但他又确实能拿到该方法会属性。这就是原型链带来的影响:当一个实例使用到本身不具备的方法或属性,他会通过原型链形式一层层向上查找,直到找不到报错的形式。
实例上自己绑定的方法或属性的优先级大于原型链上的绑定的
代码解释: (还是使用上面的例子哈
function Person() { /* 构造器 */ } ++ Person.prototype.name = 'chuguo' const person = new Person() // 初始化一个实例 console.log(person.name) // chuguo 本身在该实例上没有name属性 但在原型链上存在name 因此直接调来用
/* 实例方式或属性的与原型链上的优先级 */ function Person() { /* 构造器 */ ++ this.name = 'hello' } Person.prototype.name = 'chuguo' const person = new Person() // 初始化一个实例 console.log(person.name) // hello
Function原型
在ES6出现之前,初始化一个实例都是通过函数构造器形式进行初始化的
但有一点很特殊:实例的 __proto__
并不是指向 Function.prototype
图片解释:
代码解释:
function Person() { /* 构造器 */ } Person.prototype.name = 'chuguo' Function.prototype.name = 'function' const person = new Person() // 初始化一个实例 console.log(person.name) // chuguo console.log(person.__proto__ === Function.prototype) // false 实例的原型对象并不等于Function的原型对象 console.log(Person.__proto__ === Function.prototype) // true 能理解为每个函数构造器都是 函数原型实例化的结果
总结
总的来说:原型与原型链的出现大大补充JavaScript关于继承的缺失。
总结给大家推荐一个实用面试题库
1、前端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库