JavaScript原型详解(通俗易懂)
JavaScript原型详解
1,前言
下面是2008年Github创建以来,各种编程语言的排名情况
其中JavaScript自2013年之后就盘踞第一名,成为github上被使用最多的语言,早期,JS的使用还主要集中于浏览器中,但是随着node.js进军服务器开发和React Native逐渐向移动端渗透,一个属于JS的全栈时代就要来临了。而且JS界还流传一句名言:“所有能用JS开发的应用程序,最终都会用JS来开发”。我就问你怕不怕?
好了,说了这么多,我并不是想说JS为世界上最好的语言(显然PHP才是,对吧?←_←),也不是觉得JS会替代谁,我只是觉得,JavaScript将会是一个大家(不止web端)都应该了解和学习的语言工具。
2,面对对象(OOP)
2.1 实现思路
面对对象是大家都很熟悉的程序设计思想,是对真实世界的抽象,目前主要OOP语言用来实现面对对象的基础是类,通过类的封装,继承来映射真实世界。包括Java,C#,甚至是python等都通过类的设计来实现面对对象。但是细想起来也会觉得有问题,因为真实世界其实没有类这种概念,只有一个个不同的对象,真实世界中,继承关系发生在对象和对象之间,而不是类。就比如孩子是对象,父母也是对象,孩子(对象)继承自父母(对象)
JS也是面对对象的编程语言,只不过它实现面对对象的思路是基于原型(prototype),而不是类。这种思路也叫对象关联(Object Link Other Object),即在对象上直接映射那种真实世界的关系(如继承)。
2.2 原型概念
相关的概念其实我研究了好几天,除开原型概念本身,与之联系的对象的产生,构造函数,proto,prototype的区别,为什么对象没有prototype这个指向原型的属性,而是使用proto来指向原型?
好,我们先来谈谈原型这个概念。JS中一切皆对象,而每个对象都有一个原型(Object除外),这个原型,大概就像Java中的父类,所以,基本上你可以认为原型就是这个对象的父对象,即每一个对象(Object除外)内部都保存了它自己的父对象,这个父对象就是原型。一般创建的对象如果没有特别指定原型,那么它的原型就是Object(这就很类似Java中所有的类默认继承自Object类)。
2.3 对象创建
在JS中,对象创建的方法有很多种,最常见的如下:
//第一种,手动创建
var a={'name':'lala'}; //第二种,构造函数
function A(){this.name='lala';
}
var a=new A();//第三种,class (ES6标准写法)class A{constructor(){//super();此处没有使用extends显式继承,不可使用super()this.name='lala';}
}
var a=new A()
//其实后面两种方法本质上是一种写法
这三种写法创建的对象的原型(父对象)都是Object,需要提到的是,ES6通过引入class ,extends等关键字,以一种语法糖的形式把构造函数包装成类的概念,更便于大家理解。是希望开发者不再花精力去关注原型以及原型链,也充分说明原型的设计意图和类是一样的。
2.3 查看对象原型
当对象被创建之后,查看它们的原型的方法不止一种,以前一般使用对象的proto属性,ES6推出后,推荐用Object.getPrototypeOf()方法来获取对象的原型
function A(){this.name='lala';
}
var a=new A();
console.log(a.__proto__)
//输出:Object {}//推荐使用这种方式获取对象的原型
console.log(Object.getPrototypeOf(a))
//输出:Object {}
无论对象是如何创建的,默认原型都是Object,在这里需要提及的比较特殊的一点就是,通过构造函数来创建对象,函数A本身也是一个对象,而A有两个指向表示原型的属性,分别是proto和prototype,而且两个属性并不相同
function A(){this.name='lala';
}
var a=new A();
console.log(A.prototype)
//输出:Object {}console.log(A.__proto__)
//输出:function () {}
console.log(Object.getPrototypeOf(A))
//输出:function () {}
函数的的prototype属性只有在当作构造函数创建的时候,把自身的prototype属性值赋给对象的原型。而实际上,作为函数本身,它的原型应该是function对象,然后function对象的原型才是Object。
总之,建议使用ES6推荐的查看原型和设置原型的方法。
2.4 原型的用法
其实原型和类的继承的用法是一致的:当你想用某个对象的属性时,将当前对象的原型指向该对象,你就拥有了该对象的使用权了。
function A(){this.name='world ';
}
function B(){this.bb="hello"}
var a=new A();
var b=new B();Object.setPrototypeOf(a,b);
//将b设置为a的原型,此处有一个问题,即a的constructor也指向了B构造函数,可能需要纠正
a.constructor=A;
console.log(a.bb)
//输出 hello
(增补)
如果使用ES6来做的话则简单许多,甚至不涉及到prototype这个属性
class B{constructor(){this.bb='hello'}
}
class A extends B{constructor(){super()this.name='world'}
}var a=new A();
console.log(a.bb+" "+a.name);
//输出hello worldconsole.log(typeof(A))
//输出 "function"
怎么样?是不是已经完全看不到原型的影子了?活脱脱就是类继承,但是你也看得到实际上类A 的类型是function,所以说,本质上class在JS中是一种语法糖,JS继承的本质依然是原型,不过,ES6引入class,extends 来掩盖原型的概念也是一个很友好的举动,对于长期学习那些类继承为基础的面对对象编程语言的程序员而言。
我的建议是,尽可能理解原型,尽可能用class这种语法糖。
2.5 原型链
这个概念其实也变得比较简单,可以类比类的继承链条,即每个对象的原型往上追溯,一直到Object为止,这组成了一个链条,将其中的对象串联起来,当查找当前对象的属性时,如果没找到,就会沿着这个链条去查找,一直到Object,如果还没发现,就会报undefined。那么也就意味着你的原型链不能太长,否则会出现效率问题。
3,总结
- 对于原型概念的理解
- 类比类的继承,对象的原型可以理解为对象的父对象
- 原型的运用
- 尽可能使用ES6的标准,使用class,extends,Object.getPrototype(),Object.setPrototype()等等
- 需要注意的点
- 原型继承链条不要太长
指定原型时,注意constructor也会改变。
- 原型继承链条不要太长
4,后记(增补)
还有人觉得我的分析很抽象,所以,我再总结一下,如果要一句话理解JS中的原型是什么,那就是,对象的原型就指的对象的父对象。每个对象都有父对象,父对象本身也有父对象(爷对象?)。而原型链呢,很像过去家谱的概念,可以从你往上追溯你父亲,到爷爷,到太爷爷一直到头,这就形成了一个链条,如果其中每个人都比作一个对象,那么这个链条就是原型链。
JavaScript原型详解(通俗易懂)相关推荐
- JavaScript原型详解
1,前言 下面是2008年Github创建以来,各种编程语言的排名情况 排名 其中JavaScript自2013年之后就盘踞第一名,成为github上被使用最多的语言,早期,JS的使用还主要集中于浏览 ...
- JavaScript事件详解-jQuery的事件实现(三)
正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...
- JavaScript正则表达式详解(一)正则表达式入门
JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...
- Javascript 函数详解
Javascript 函数详解 1)函数声明: 通过关键字function定义,把函数作为变量来声明 函数声明后不会立即执行,会在我们需要的时候调用到. <script>function ...
- JavaScript对象详解
转载请注明预见才能遇见的博客:https://my.csdn.net/ 原文地址:https://blog.csdn.net/weixin_42787326/article/details/81297 ...
- 【第二篇】SAP HANA XS使用JavaScript编程详解
前言部分 大家可以关注我的公众号,公众号里的排版更好,阅读更舒适. 正文部分 在第一篇的时候,我们说过如下内容: SAP HANA XS支持JavaScript中的服务器端应用程序编程.开发的服务器端 ...
- JavaScript 数据类型详解(对象、set、map)
在上一篇博客中我已经详细介绍了JavaScript 中的字符串和数组,没看过的戳[JavaScript 数据类型详解(字符串.数组)]哦,现在我们来看看对象(Object)和 ES6 新增的 Set ...
- javascript冒泡排序详解---kalrry
javascript冒泡排序详解---kalrry 一.什么是冒泡排序 二.举个例子 一.什么是冒泡排序 冒泡排序,Bubble Sort,通过依次来比较相邻两个元素的大小,在每一次的比较的过程中,两 ...
- JavaScript闭包详解及案例
JavaScript闭包详解及案例 一. 变量作用域 函数内部可以使用全局变量 函数外部不可以使用局部变量 当函数执行完毕时,本作用域内的局部变量会被销毁 二. 闭包 闭包:有权访问另一个函数作用域中 ...
最新文章
- 干货 | 漫谈图神经网络
- JVM 内存区域大小参数设置
- C++Runge-Kutta龙格-库塔法求非线性常微分方程的解(附完整源码)
- 吐槽贴:用ELECTRA、ALBERT之前,你真的了解它们吗?
- linux3.10修复i2c adapter无法使用dts创建device
- 静态tableview组背景色的更改及自定义cell的两种方式
- animate改变背景颜色_3D MAX2016视口背景设置里各参数的含义详解 - 3dmax基础操作入门教程-3dmax材质教程,3d材质贴图教程参数,vray材质参数,3dmax贴图教程...
- 八达岭长城 景区 导游图 、地图、大图、高清、超高清
- 2.3.1 TextView(文本框)详解
- 将类似html数据打印机,白激光打印机的工作原理.doc
- 坐骨神经痛!到底是梨状肌综合征还是腰椎间盘呢?
- 小白也能开始VCS+Verdi的旅程
- nodejs addon
- 阿根廷夺冠!梅西圆梦!历届世界杯还有哪些数据看点?
- 牧场物语矿石镇的伙伴们详细攻略
- 局域网怎么查看单位摄像头_简单易用,夜里看的更清楚,360新品水滴摄像头夜视版实测...
- centos7搭建集群过程
- xss-platform平台的入门搭建
- 微信小程序开发实战(15):视频组件(video)
- 【Linux】快捷键
热门文章
- SaaS路线图 | 时光机
- 亚马逊云科技 + 英特尔 + 中科创达为行业客户构建 AIoT 平台
- 韩剧TV APP案例分析
- 搭建量化交易系统接口的步骤是什么?
- oracle mapviewer 11g安装使用,Oracle MapViewer11g安装与部署
- 两款截然不同的摩托车游戏
- ERROR org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
- python写水仙花_python简易实现任意位数的水仙花实例
- == 和 ===区别
- 计算机带不起大型游戏怎么回事,电脑玩不起来大型网络游戏怎么办