作者 魏楷聪 发布于 2015年01月20日
一种面向对象语言需要向开发者提供四种基本能力:
1. 封装 - 把相关的信息(无论数据或方法)存储在对象中的能力
2. 聚集 - 把一个对象存储在另一个对象内的能力
3. 继承 - 由另一个类(或多个类)得来类的属性和方法的能力
4. 多态 - 编写能以多种方法运行的函数或方法的能力
在JavaScript中,所有对象都是从Object对象继承过来的。Object中的属性都是不可枚举的(propertyIsEnumerable返回false),因此无法通过for...in语句得到其中的属性。
在JavaScript中,可以动态添加对象的属性,也可以动态删除对象的属性。
![](https://img.haomeiwen.com/i188548/a76564d9cc4e98d3.png)
![](https://img.haomeiwen.com/i188548/eea5b5ede6c9d461.png)
1) 基于已有对象扩充其属性和方法
![](https://img.haomeiwen.com/i188548/34561e36d84340b8.png)
最后一个属性sayName实际上是指向函数的指针,意味着该属性是个方法。
2) 工厂方式(factory function)
![](https://img.haomeiwen.com/i188548/cd0ae1a483287252.png)
![](https://img.haomeiwen.com/i188548/95d867d6e87b426a.png)
![](https://img.haomeiwen.com/i188548/06ba4906055dd47c.png)
使用this,即可在任意多个地方重用同一个函数
注意:引用对象的属性时,必须使用this关键字。
function get(){
alert(username + ", " + password);
}
如果不用对象或this关键字引用变量,ECMAScript就会把它看作局部变量或全局变量。然后该函数将查找名为color的局部或全局变量,但是不会找到。结果该函数将报“username未定义”的错误。
3) 构造函数方式
![](https://img.haomeiwen.com/i188548/e37a7e5575e0256c.png)
![](https://img.haomeiwen.com/i188548/77441952c768c6fc.png)
4) 原型(“prototype”)方式
能用 instanceof 运算符检查给定变量指向的对象的类型:
alert(person1 instanceof Person); // outputs "true"
![](https://img.haomeiwen.com/i188548/c32eacada0550f00.png)
利用对象的prototype属性,可把它看成创建新对象所依赖的原型
调用new Person()时,原型的所有属性都被立即赋予要创建的对象,
意味着所有Person实例存放的都是指向getInfo()函数的指针
![](https://img.haomeiwen.com/i188548/7327c0dc44fe60d0.png)
由于username是引用值,Person的两个实例都指向同一个数组
如果使用原型方式对象,那么生成的所有对象会共享原型中的属性,这样一个对象改变了该属性(引用值)也会反映到其它对象当中。
单纯使用原型方式定义对象无法在构造函数中为属性赋初值,只能在对象生成后再去改变属性值。
使用原型+构造函数方式来定义对象,对象之间的属性互不干扰,各个对象间共享同一个方法。
![](https://img.haomeiwen.com/i188548/fa40beed791598e7.png)
用原型方式定义对象的函数属性(方法)
所有函数都只创建一次(没有内存浪费),而每个对象都具有自己的对象属性实例
5) 动态原型方式:在构造函数中通过标志量让所有对象共享一个方法,而每个对象拥有自己的属性
![](https://img.haomeiwen.com/i188548/a25273a3fb1d4ce6.png)
(完)
网友评论