资讯专栏INFORMATION COLUMN

如何理解JavaScript的原型和原型链?

adie / 688人阅读

摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。

之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。
JavaScript的特点
JavaScript是一门直译式脚本语言,是一种动态类型、基于原型的语言。 JavaScript的灵活性不亚于C++,你可以使用JavaScript尝试不同的程序设计范型。
比如类jQuery风格的函数式编程、基于过程的指令式编程、以及基于原型的面向对象编程。
不同于Java、C#等面向对象语言,JavaScript采用基于原型的继承方式。
为啥会有原型和原型链?
1994年,网景公司(Netscape)发布了Navigator浏览器0.9版,但是刚开始的Js没有继承机制,更别提像同时期兴盛的C++和Java这样拥有面向对象的概念。在实际的开发过程中,工程师们发现没有继承机制很难解决一些问题,必须有一种机制能将所有的对象关联起来。
Brendan Eich鉴于以上情况,但不想把Js设计得过为复杂,于是引入了new关键词和constructor构造函数来简化对象的设计,引入了prototype函数对象来包含所有实例对象的构造函数的属性和方法,引入了proto和原型链的概念解决继承的问题。
原型模式
每个函数都有一个prototype(原型)属性
这个属性都有一个指针,指向一个对象
这个对象包含由特定类型所有实例共享的属性和方法
使用原型的好处是可以让所有对象实例共享它包含的方法和属性
通过in操作符和hasOwnProperty来判断给定属性是来自于原型还是实例
in- true 代表属性在对象中存在 来自实例或者来自原型
hasOwnProperty- true代表属性来自于实例 是实例属性
原型链
ECMAScript中只支持实现继承,而且是通过原型链的方式来实现的。所以原型链是JavaScript实现继承的一种重要方式。
用户定义类型的原型链
我们一般如何来检查JavaScript的变量数据类型?一般我们都是通过instanceof关键字,可以基于原型链来检测变量的类型。
我们可以先构造一个原型链,再用instanceof来检测类型:


​​​​由上面讲的instanceof的结果,可以判断这些类型的继承层级:

​​事实上instanceof是通过原型链来检测类型的,例如L instanceof R: 如果R.prototype出现在了L的原型链上则返回true,否则返回false。
用JavaScript来描述instanceof的实现逻辑是这样的:

​​JavaScript原型链
先给大家看一个JavaScript的原型链结构图。

理解原型链的小技巧: 将__proto__箭头视作泛化(子类到父类)关系!
那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。
图中给出了Object.prototype.__proto__ == null,但它还没有标准化,在Chrome、Safari和Node.js下它是不同的东西。
但可以看到JavaScript中所有对象的共同隐式原型为Object.prototype,它的上一级隐式原型是什么已经不重要了, 因为它不会影响所有内置对象以及用户定义类型的原型链结构。
上图其实已经解释了不同内置对象instanceof的行为,我们来看Function和Object的特殊之处:
Object是由Function创建的:因为Object.__proto__ === Funciton.prototype;
同理,Function.prototype是由Object创建的;
Funciton是由Function自己创建的!
Object.prototype是凭空出来的!
现在我们可以解释特殊对象的instance行为了:

​​另外可以看到当你声明一个函数(比如Animal)时,Animal.prototype会自动被赋值为一个继承自Object的对象, 而且该对象的constructor等于Animal。即:
​​
值得注意的是Animal如果被Cat继承,Cat实例(比如cat)的constructor仍然是Animal。
​​
总结
1.每个函数对象都有一个 prototype 属性,这个属性就是函数的原型对象。
2.原型链是JavaScript实现继承的重要方式,原型链的形成是真正是靠__proto__ 而非prototype。

喜欢文章的可以关注小编~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103475.html

相关文章

  • 如何理解JavaScript原型原型

    摘要:之前有朋友问怎么去理解原型和原型链的问题。理解原型链的小技巧将箭头视作泛化子类到父类关系那么图中所有的虚线将构成一个继承层级,而实线表示属性引用。原型链是实现继承的重要方式,原型链的形成是真正是靠而非。 之前有朋友问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。这里给大家讲讲,方便大家记忆。 JavaScript的特点JavaScript是一门直译式脚本...

    xuexiangjys 评论0 收藏0
  • 【5】JavaScript 函数高级——原型原型深入理解(图解)

    摘要:探索是如何判断的表达式如果函数的显式原型对象在对象的隐式原型链上,返回,否则返回是通过自己产生的实例案例案例重要注意的显示原型和隐式原型是一样的。面试题测试题测试题报错对照下图理解 原型与原型链深入理解(图解) 原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有...

    马龙驹 评论0 收藏0
  • 深入理解JavaScript系列5:强大原型原型

    摘要:参考内容关于本文本文转自大叔的深入理解系列深入理解系列文章,包括了原创,翻译,转载,整理等各类型文章,原文是大叔的一个非常不错的专题,现将其重新整理发布。 前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型。 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大。实现传统的类继承模型是很简单,但是...

    frontoldman 评论0 收藏0
  • 非科班如何理解闭包,原型原型,继承

    摘要:闭包,原型,原型链,继承对象若干属性的集合输出的集中类型标识,其中上面的四种属于简单的值类型,不是对象。在实际应用中如何区分一个属性到底是基本的还是从原型中找到的呢,特别是在循环中由于所有的对象的原型链都会找到,因此所有的对象都会有的方法。 闭包,原型,原型链,继承 对象——若干属性的集合 typeof输出的集中类型标识,其中上面的四种(undefined, number, strin...

    xuexiangjys 评论0 收藏0
  • 详解javascript

    摘要:原文地址详解的类博主博客地址的个人博客从当初的一个弹窗语言,一步步发展成为现在前后端通吃的庞然大物。那么,的类又该怎么定义呢在面向对象编程中,类是对象的模板,定义了同一组对象又称实例共有的属性和方法。这个等同于的属性现已弃用。。 前言 生活有度,人生添寿。 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客   Javascript从当初的一个弹窗语言,一...

    hufeng 评论0 收藏0

发表评论

0条评论

adie

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<