原型和原型链

1|0原型链

1|1概述:

原型链是 JavaScript 实现继承的方式。

1|2原型:

function Person() { this.name = 'Tomy'; } const man = new Person(); man.name; //"Tomy" man.__proto__ === Person.prototype; //true Person.prototype.constructor === Person; //true

如上段代码演示, man 是由构造函数 Person 所生成的实例。

实例 man 的隐式原型 __proto__ 指向构造函数 Person 的显式原型 prototype

而原型 prototypeconstructor 又指向本构造函数 Person

function Person() { this.name = 'Tomy'; } function Worker() { this.salary = 1000; } const man = new Worker(); man.salary; //1000 man.name; //undefined // 挂载原型 const people = new Person(); man.__proto__ = people; man.name; //"Tomy" man.hasOwnProperty('salary'); //true man.hasOwnProperty('name'); //false

Worker 生成的实例 man 只有 salary 属性存在。

man__proto__ 挂载到 people 之后便能访问到 name 属性。

原因在于:当 js 对象没有该属性时,会在其所在的原型链上寻找相应原型的属性,直到找到或到达顶层原型(Objectprototypenull)。

1|3new 关键字

由于 JavaScript 通过原型链的实现方式,new 关键字的作用不仅在于创建新的对象,同时也实现原型的继承。

function Person() { this.name = 'Tomy'; this.setName = function(name) { this.name = name; }; } function createInstance(fn) { const relt = {}; relt.__proto__ = fn.prototype; fn.call(relt); return relt; } const instance = createInstance(Person); instance.name; //"Tomy" instance.setName('Jack'); instance.name; //"Jack"

new 关键字的作用就类似于上段代码中的 createInstance

1|4class 、 extends 、 super

classES6 新出现的语法,其创建实例的方式依旧是原型链。

class Person { constructor() { this.name = 'Tomy'; } work(){ return 'job' } } class Worker extends Person { constructor() { super() this.salary = 1000; } draw(){ return '领取' + this.salary } } const man = new Worker(); man.name; //"Tomy" man.work(); //"job" man.salary; //1000 man.draw(); //"领取1000" man.hasOwnProperty('salary'); //true man.hasOwnProperty('name'); //true man.hasOwnProperty('work'); //false man.hasOwnProperty('draw'); //false man.__proto__ === Worker.prototype; //true man.__proto__.hasOwnProperty('draw'); //true man.__proto__.hasOwnProperty('work'); //false man.__proto__.__proto__ === Person.prototype; //true man.__proto__.__proto__.hasOwnProperty('work'); //true

如上演示,class 中函数的 this 均指向了实例本身。

class 中的函数挂载在 prototype 上,而并不挂载在实例上。

若继承的父类 class 存在 constructor,则子类 class 必须调用 super() 使实例上也有父类的属性。

1|5Function

FunctionArrayNumberDate 等同样是继承于 Object

不同的是其余构建函数都返回一个实例,而Function返回动态函数。

Function.prototype.__proto__.constructor === Object //true const fn = new Function('arg1','arg2','arg3','return arg1 + arg2 + arg3') fn //ƒ anonymous(arg1,arg2,arg3) {return arg1 + arg2 + arg3} typeof fn //'function' fn.a = 1 fn.a //1

Function 的优点在于可以创建动态函数,但其性能比传统直接定义的方式开销大。

1|6instanceof 关键字

class Person {} class Worker extends Person {} const man = new Worker() man instanceof Worker //true man instanceof Person //true man instanceof Object //true man instanceof Array //false

当构建函数在其原型链上即返回 true

function isExtendsOf(Fn){ let proto = this.__proto__; do{ if(proto.constructor === Fn){ return true } proto = proto.__proto__ }while(proto) return false } class Person {} class Worker extends Person {} const man = new Worker() isExtendsOf.call(man,Worker) //true isExtendsOf.call(man,Person) //true isExtendsOf.call(man,Array) //false

instanceof 类似于如上代码中的 isExtendsOf


__EOF__

本文作者Odyssey
本文链接https://www.cnblogs.com/qingzhao/p/16499090.html
关于博主:I am a good person
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   --Odyssey--  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示