JavaScript原型详解

1,前言
下面是2008年Github创建以来,各种编程语言的排名情况

JavaScript原型详解

文章插图
 
排名
其中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 原型的用法
其实原型和类的继承的用法是一致的:当你想用某个对象的属性时,将当前对象的原型指向该对象,你就拥有了该对象的使用权了 。
【JavaScript原型详解】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复制代码


推荐阅读