一篇文章让你彻底了解 JS 原型链

2022-12-15 程序员资讯 0 251
¥ 2.88B

包年VIP免费升级包年VIP

开通VIP尊享优惠特权
立即下载 升级会员

序言

蓝本是 JavaScript 中两个较为难认知的基本概念,蓝本有关的特性也较为多,第一类有”[[prototype]]”特性,表达式第一类有”prototype”特性,蓝本第一类有”constructor”属性。

重新认识蓝本(甚么是蓝本)

已经开始蓝本的如是说以后,他们具体来说说说甚么是蓝本?

表述

在 JavaScript 中,蓝本也是两个第一类,透过蓝本能同时实现第一类的特性承继,JavaScript 的第一类中都包涵了两个”[[prototype]]”外部特性,那个特性大部份关联的是该第一类的蓝本。”[[prototype]]”做为第一类的外部特性,是无法被间接出访的。大部份为的是方便快捷查阅两个第一类的蓝本,Chrome 等小型应用程序厂商提供更多了”proto”那个冗余的出访器(ECMA 导入了国际标准第一类蓝本出访器 “Object.getPrototype(Object)”)

示例预测

function Animal(name, type) { this.name = name; this.type = type; this.getInfo = function(){ console.info(“现阶段鸟类特性==>”,this.name + is + this.type) } } let dog = new Animal(“狗”, “有蹄类哺乳类”) // 现阶段鸟类特性==> 狗is有蹄类哺乳类

Step–>1: 查阅第一类 dog 的蓝本

console.info(“__proto__”,dog.__proto__); // __proto__ Objectconstructor: Animal(name, type)__proto__: console.info(“constructor=====>”,dog.constructor) //constructor=====> Animal(name, type) { // this.name = name; // this.type = type; // this.getInfo = function(){ // console.info(“现阶段鸟类特性==>”,this.name + is + this.type)

结果预测

“Animal{}”第一类是 dog 的蓝本,透过 Chrome 展开能看到,”Animal{}”做为两个蓝本第一类,也有”proto”特性(有关联蓝本的蓝本)在这段代码中,还用到”constructor”特性。在 JavaScript的第一类蓝本第一类中。还包涵两个”constructor”特性,那个特性有关联创建大部份指向该蓝本的示例的构造表达式// 拓展 能判断两个第一类是不是数组类型 function isArray(arr){ return arr.constructor.toString().indexOf(“Array”) > -1; }

*在这里,dog 第一类本身没有”constructor”那个特性,但是透过蓝本链查找,找到了 dog 蓝本(dog.proto)的 “constructor”特性,并找到了Animal表达式

Step–>2: 查阅第一类 dog 的蓝本(dog.proto)的蓝本

既然 dog 的蓝本”Animal{}”也是两个第一类,那么他们就同样能来查阅 dog 的蓝本(dog.proto)的蓝本

console.info(dog.__proto__ === Animal.prototype) console.info(Animal.prototype.__proto__) console.info(Animal.prototype.constructor) console.info(Animal.prototype.constructor === Animal)

结果预测

具体来说看”dog.proto === Animal.prototype”,在 JavaScript 中,每个表达式都有两个 prototype 特性,当两个表达式被用作构造表达式来创建示例时,该表达式的 prototype 特性值将被做为蓝本赋值给大部份对象示例(也是设置示例的proto特性),也是说,大部份示例的蓝本引用的是表达式的 prototype 特性。介绍了构造表达式的 prototype 特性之后。一定就会明白为甚么第一句是 true 了当通对于蓝本第一类”Animal.prototype”第一类的”constructor”根据前面的如是说,将有关联 Animal 表达式本身。

透过上面能看到,”Animal.prototype”第一类和 Animal 表达式第一类透过”constructor”和 “prototype”特性同时实现了相互引用

Step–>3: 查阅第一类 Object 的蓝本

透过前一部分能看到,will的蓝本的蓝本是”Object{}”第一类。实际上在JavaScript中,大部份第一类的蓝本都将追溯到”Object {}”第一类。下面透过一段代码看看”Object {}”第一类:

console.log(Animal.prototype.__proto__ === Object.prototype); console.log(typeof Object); console.log(Object); console.log(Object.prototype); console.log(Object.prototype.__proto__); console.log(Object.prototype.constructor);

结果预测

Object第一类本身是一个表达式第一类。既然是Object表达式,就肯定会有prototype特性,所以能看到”Object.prototype”的值是”Object {}”那个蓝本第一类。反过来,当出访”Object.prototype”第一类的”constructor”那个特性的时候,就得到了Obejct表达式。,也是说”Object {}”蓝本第一类是蓝本链的终点了。

Step–>4: 查阅第一类Function的蓝本

在上面的例子中,Animal是两个构造表达式,在JavaScript中表达式也是第一类,所以,我们也能透过”proto”特性来查找Animal表达式第一类的蓝本。

console.log(Animal.__proto__ === Function.prototype); console.log(Animal.constructor === Function) console.log(typeof Function); console.log(Function); console.log(Function.prototype); console.log(Function.prototype.__proto__); console.log(Function.prototype.constructor);

结果预测

在JavaScript中有个Function第一类(类似Object),那个第一类本身是个表达式;大部份的表达式(包括Function,Object)的蓝本(proto)都是”Function.prototype”。Function第一类做为两个表达式,就会有prototype特性,该特性将有关联”function () {}”第一类。Function第一类做为两个第一类,就有”proto”特性,该特性有关联”Function.prototype”,也是说,”Function.proto === Function.prototype”对于Function的蓝本第一类”Function.prototype”,该蓝本第一类的”proto”特性将有关联”Object {}”

对比 prototype 和 proto

对于”prototype”和”proto”这两个特性有的时候可能会弄混,”Person.prototype”和”Person.proto”是完全不同的。

在这里对”prototype”和”proto”进行简单的如是说:

对于大部份的第一类,都有proto特性,那个特性有关联该第一类的蓝本对于表达式第一类,除了proto特性之外,还有prototype特性,当两个表达式被用作构造表达式来创建示例时,该表达式的prototype特性值将被做为蓝本赋值给大部份第一类示例(也是设置示例的proto特性)

一篇文章让你彻底了解 JS 原型链

对于上图的总结如下:

所有的第一类都有”proto”特性,该特性有关联该第一类的蓝本大部份的表达式第一类都有”prototype”特性,该特性的值会被赋值给该表达式创建的第一类的”proto”特性大部份的蓝本第一类都有”constructor”特性,该特性有关联创建大部份指向该蓝本的示例的构造表达式表达式第一类和蓝本第一类透过”prototype”和”constructor”特性进行相互关联因为每个第一类和蓝本都有蓝本,第一类的蓝本指向第一类的父,而父的蓝本又指向父的父,这种蓝本层层连接起来的就构成了蓝本链。

hasOwnProperty

“hasOwnProperty”是”Object.prototype”的两个方法,该方法能判断两个第一类是否包涵自表述特性而不是蓝本链上的特性,因为”hasOwnProperty” 是 JavaScript 中唯一两个处理特性但是不查找蓝本链的表达式。

相信你还记得该文最已经开始的例子中,透过dog他们能出访”constructor”那个特性,并得到dog的构造表达式Animal。这里结合”hasOwnProperty”那个表达式就能看到,dog第一类并没有”constructor”那个特性。

从下面的输出能看到,”constructor”是dog的蓝本(dog.proto)的特性,但是透过蓝本链的查找,dog第一类能发现并使用”constructor”特性。

“hasOwnProperty”还有两个重要的使用场景,是用来遍历第一类的特性。

function Person(name, age){this.name = name; this.age = age;}Person.prototype.getInfo = function(){ console.log(this.name + ” is ” + this.age + ” years old”);};var will = new Person(“Will”, 28);for(var attr in will){ console.log(attr);}// name// age// getInfofor(var attr in will){ if(will.hasOwnProperty(attr)){ console.log(attr); }}// name// age

总结

本文如是说了JavaScript中蓝本有关的基本概念,对于蓝本能归纳出下面一些点:

大部份的对象都有”[[prototype]]”特性(透过proto出访),该特性有关联第一类的蓝本大部份的表达式第一类都有”prototype”特性,该特性的值会被赋值给该表达式创建的第一类的”proto”特性大部份的蓝本第一类都有”constructor”特性,该特性有关联创建大部份指向该蓝本的示例的构造表达式表达式第一类和蓝本第一类透过”prototype”和”constructor”特性进行相互关联透过这些如是说,相信一定能对蓝本有个清晰的重新认识。

举报/反馈

资源下载此资源下载价格为2.88B,包年VIP免费,请先
2405474279

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务