对于事物的理解,往往需要涵盖三个方面:它是什么样子的?它为何会出现?它的外延是什么?理解了内涵与外延才算真正的掌握。
一、原型是什么
以对象a为例,a内部有一个隐藏的链接指向另一个对象b,则a的原型(也叫原型对象)是b;同时b也有链接指向c,以此类推,最终指向的是Object.prototype。以上也解释了什么是原型链。
1.1 令人困惑的prototype
原型之所以使人困惑是因为人们往往把它和prototype属性混在一起,其实这是命名上的失败,对象的原型不是它的属性,而是它的特性。为了便于区分,我将对象的原型称为“原型”,将原型属性称为prototype属性,但两者之间又是紧密相连的,因为有了prototype属性才有了原型。
1.2 prototype属性
每个JavaScript方法都有一个prototype属性;当你定义一个方法var A = function() {}时,实际上它等价于以下代码:
也就是说,当你创建了一个方法的时候,JavaScript会将Object.prototype赋值给方法的prototype属性。
1.2.1 Object.prototype
前面已经说过每个JavaScript方法都有一个prototype属性,所以Object也是一个方法,从使用角度看是一个构造方法。Object.prototype是所有JavaScript对象原型链的最末端(除特殊情况:人为的将原型设置为null)。此外需要说明的是:从JavaScript的语法角度看,并没有构造方法的定义,人们只是根据用途将某些方法称为构造方法,本质上构造方法与一般的方法并没有区别。
二、原型的应用
2.1 被人们忽视的原型
如果你一直从事轻前端重后端的web项目,一直在编写意大利面条式的代码,且这种代码还能满足开发与维护的需求,你确实不需要了解原型。当你发觉JavaScript的代码量在项目中急速增长,代码逐渐变的难以阅读、难以维护时,你开始寻找一种全新的开发模式来组织代码---OOP。OOP作为一种成熟的开发思想在组织大型项目时,优势尤为明显。JavaScript在创建之初就已经支持OOP了,而支撑OOP的就是原型。
2.1 创建对象
在JavaScript中创建对象有以下三种方式:
很显然只有第三种方式才符合OOP的思想,因为它体现了class(类)的概念。在JavaScript的语法层次是没有class的定义的,但是可以通过function来模拟class的行为,通过原型来实现继承。
2.2 JavaScript中的“class”
JavaScript通过function来模拟class,示例代码如下:
通过new操作符,对象a1、a2就拥有了A方法中this所拥有的属性。
2.2 JavaScript中的继承
JavaScript是通过原型来实现继承的,示例代码如下:
new操作的内存分析:
-
当执行 var c = new Child();
时,首先创建了一个新的空对象
"内存分析-1"
-
将Child方法中的this指向新对象,通过this进行对象初始化
"内存分析-2"
-
将Child的prototype属性( new Parent()
)作为新对象的原型
"内存分析-3"
原文:http://www.jianshu.com/p/0446575d4a7e