一篇文章让你搞懂JavaScript 原型和原型链
本文由葡萄城技术团队原创并首发
网络推广网站推广转载请注明出处
与多数面向对象的开发语言有所不同,虽然JavaScript没有引入类似类的概念(ES6已经引入了class语法糖),但它仍然能够大量的使用对象,那么如何将所有对象联系起来就成了问题。于是就有了本文中我们要讲到的原型和原型链的概念。
原型和原型链作为深入学习JavaScript最重要的概念之一,如果掌握它了后,弄清楚例如JavaScript的继承,new关键字的原来、封装及优化等概念将变得不在话下,那么狼蚁网站SEO优化我们开始关于原型和原型链的介绍。
什么是原型?
JS中的对象包含了一个prototype的内部属性,这个属性所对应的就是该对象的原型。
我们先看下图a、b、c 分别为数组、对象、函数。
可以看到,三者都有一个属性__proto__
这个 __proto__ 称作 隐式原型。
除此之外,c还有一个属性prototype
这个prototype 称作 显式原型。
小结一下
- 所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
- 所有函数除了有_proto_属性之外还拥有prototype属性(显式原型)
- 原型对象每创建一个函数,该函数会自动带有一个prototype属性,该属性是一个指针,指向了一个对象,我们称之为原型对象。
函数除了有_proto_属性之外还拥有prototype属性,我们借助构造函数来寻找二者之间的关系。如下图
如下(结合上图更容易理解)
1. 实例对象a只有__proto__(隐式原型),构造函数既有 __proto__(隐式原型)也有prototype(显式原型)
2. __proto__ 和 prototype 都是一个对象,既然是对象,就表示他们也有一个 __proto__
a.__proto__.__proto__ A.prototype.__proto__
3.实例对象a的隐式原型指向它构造函数的显式原型,指向的意思是恒等于
a.__proto__ === A.prototype
4. 当调用某种方法或查找某种属性时,会在自身调用和查找,如果自身并没有该属性或方法,则会去它的__proto__属性中调用查找,也就是它构造函数的prototype中调用查找。
什么是原型链?
先看下图,提出一个问题
1. 在 Object的显式原型添加属性b,为什么 示例对象p 能使用此属性呢? p.b = b
2. 为什么 p.a 为undefined
如下图所示
1. 实例对象p的隐式原型(__proto__)是一个对象,有两个属性值constructor 和 __proto__
2. p.__proto__.constructor 返回的结果为构造函数Person
3. p.__proto__.__proto__ .constructor 返回的结果为Object()函数
结合上面所讲的显式原型与隐式原型之间的关系,等同如下
p.__proto__.__proto__ = Object.prototype
所以p.b打印结果为b,p没有b属性,会一直通过__proto__向上查找,当查找到Object.prototype时找到,打印出b,向上查找过程中,得到的是Object.prototype,而不是Function.prototype,找不到a属性,所以结果为undefined,这就是 原型链,通过__proto__向上进行查找,最终到null结束。
1. 查找属性,如果本身没有,则会去__proto__中查找,也就是构造函数的显式原型中查找,如果构造函数的显式原型中也没有该属性,因为构造函数的显式原型也是对象,也有__proto__,那么会去它的显式原型中查找,一直到null,如果没有则返回undefined
2. p.__proto__.constructor == function Person(){}
3. p.___proto__.__proto__== Object.prototype
4. p.___proto__.__proto__.__proto__== Object.prototype.__proto__ == null
5. 通过__proto__形成原型链而非protrotype
什么是原型继承?
Person.prototype 只是一个指针,指向的是原型对象,这个原型对象并不特别,它也只是一个普通对象。假设说,这时候,我们让 Person.prototype 不再指向最初的原型对象,而是另一个类 (Animal)的实例,情况会怎样呢?
执行该代码 Person.prototype = new Animal() 后,Person的prototype指针指向发生了变化,指向了一个 Animal 实例。
当 p 去访问 address 属性时,js会先在 p 的实例属性中查找,发现找不到后,就会去 Person 的原型对象上 查找。因为Person的原型对象已经被我们换成一个animal实例,所以就会先找animal实例的属性,当发现还是没有 address属性,就会去Animal的原型对象上查找,最终找到。
这就说明,我们可以通过原型链的方式,实现 Person 继承 Animal 的所有属性和方法。
看到这,相信大家对原型和原型链的概念应该已经有了一定了解了,如果仍然不太理解,也不用气馁,因为闭包及原型链是JavaScript最难理解的几部分。相信之后在不断的开发实践中会使你理解的更为透彻,多学习多思考才能更快掌握。如果大家有任何反馈和问题,也欢迎通过评论区告诉我,谢谢。
以上就是一篇文章让你搞懂JavaScript 原型和原型链的详细内容,更多关于JavaScript 原型和原型链的资料请关注狼蚁SEO其它相关文章!
编程语言
- 甘肃哪有关键词排名优化购买方式有哪些
- 甘肃SEO如何做网站优化
- 河南seo关键词优化怎么做电话营销
- 北京SEO优化如何做QQ群营销
- 来宾百度关键词排名:提升您网站曝光率的关键
- 卢龙关键词优化:提升您网站排名的策略与技巧
- 山东网站优化的注意事项有哪些
- 四川整站优化怎样提升在搜索引擎中的排名
- 疏附整站优化:提升网站性能与用户体验的全新
- 海南seo主要做什么工作售后服务要做到哪些
- 荣昌百度网站优化:提升您网站的搜索引擎排名
- 河北seo网站排名关键词优化如何做SEO
- 江西优化关键词排名推广售后保障一般有哪些
- 古浪SEO优化:提升你的网站可见性
- 西藏网站排名优化怎么把网站排名在百度首页
- 如何提升阳东百度快照排名:详尽指南