JavaScript 原型与继承机制详解

  初识 JavaScript 对象的时候,我以为 JS 是没有继承这种说法的,虽说 JS 是一门面向对象语言,可是面向对象的一些特性在 JS 中并不存在(比如多态,不过严格来说也没有继承)。这就困惑了我很长的时间,当我学习到 JS 原型的时候,我才发现了 JS 的新世界。本篇文章讲解了 JavaScript new 操作符与对象的关系、原型和对象关联(也就是俗称的继承)的原理,适合有一定基础的同学阅读。

你不知道的JavaScript(上卷+中卷)高清晰PDF 下载建见

 一、JavaScript 的类与对象

  许多书籍上都会说到如何在 JS 当中定义“类”,通常来讲就是使用如下代码:

1 function foo () { 2 this.x = 1; 3 this.y = 2; 4 } 5 var obj = new foo(); //{x:1, y:2}

  实际上这一个很糟糕的语言机制,我们首先要明确,在 JS 当中根本没有“类”这种东西。在了解它之前,我们要先来了解下 JS 的发展历史。

  JavaScript 随着互联网和浏览器而诞生,在早些年代,互联网还比较贫乏,上网的成本也比较高,网速非常的慢,通常需要花很长的时间才能传输完一个纯文本的 HTML 文件。所以那时候 Netscape 就提出,需要有一种解决方案,能使一些操作在客户端进行而不需要通过服务器处理,比如用户在填写邮箱的时候少写了一个“@”,在客户端就可以检查出错误并提示用户而不需要在服务器进行解析,这样就可以极大的降低通信操作带来了延迟和带宽消耗。而那时候,正巧 JAVA 问世,火的那叫个一塌糊涂,所以 Netscape 决定和 SUN 合作,在浏览器当中植入 JAVA 小程序(后来称Java applet)。不过后来就这一方案产生了争议,因为浏览器本来只需要很小的操作,而 JAVA 语言本身太“重”了,用来处理什么表单验证的问题实在是大材小用,所以决定开发一门新的语言来支持客户端的轻量级操作,而又要借鉴 JAVA 的语法。于是乎 Netscape 开发出了一门新的轻量级语言,在语法方面偏向于 C 和 JAVA,在数据结构方面偏向于 JAVA,这门语言最初叫做 Mocha,后来经过多年的演变,变成了现在的 JavaScript。

  故事说道这里,好像和本文并没有什么关系...别急,马上就要说道点子上了。这个语言为什么要取名 JavaScript 呢,其实它和 JAVA 并没有半毛钱的关系,只是因为在那点年代,面向对象方法问世才不久,所有的程序员都推崇学习面向对象方法,再加上 JAVA 的横空出世和大力宣传,只要和 JAVA 沾边的东西就像是往脸上贴了金一样,自带光环。所以便借助了 JAVA 的名气来进行宣传,不过光是嘴皮子宣传还不行,因为面向对象方法的推崇,大家都习惯于面向对象的语法,也就是 new Class() 的方法编写代码。不过 JavaScript 语言本身并没有类的概念,其是多种语言的大杂烩,为了更加贴合习惯了面向对象语法的程序员,于是 new 操作符诞生了。

  好了,说了这么大一堆故事,就是想告诉同学们,new 操作符在 JavaScript 当中本身就是一个充满歧义的东西,它并不存在类的概念,只是贴合程序员习惯而已。那么在 JavaScript 当中 new 操作符和对象究竟有什么关系呢?思考下面这一段代码:

1 function foo () { 2 this.x = 1; 3 this.y = 2; 4 return { 5 z:3 6 } 7 } 8 var obj = new foo(); //{z:3}

  咦?发生了什么奇怪的事情,x 和 y 哪里去了?实际上 new 操作符并不是传统面向对象语言那样,创建一个类的实例,new 操作符实际上只是在引擎内部帮我们在函数的开始创建好了一个对象,然后将函数的上下文绑定到这个对象上面,并在函数的末尾返回这个对象。这里需要注意的问题是,如果我们手动的返回了一个对象,那么按照函数执行机制,一旦返回了一个值,那么该函数也就执行结束,后面的代码将不会执行,所以说在刚才的例子中我们得到的对象只是我们手动定义的对象,并不是引擎帮我们创建的对象。 new 操作符实际上类似于以下操作:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9fffa9f22ed89d78b1b09dc5ec45d6c5.html