标签:javascript
下午刚刚看完了《JavaScript高级程序设计》中的第六章,面向对象的程序设计,因为自己以前没有面向对象程序设计的基础,所以理解得有些困难,但是通过自己的努力研读+上网查资料+反复实践,总算是答题上理解了,对我的编程思维算是一个很大的提高吧,这里把学习笔记和心得发一下,方便以后自己查阅。
一、理解对象
在JavaScript中,一切皆是对象,前面学习引用类型,基本都是JavaScript中的内置对象,而基本类型,则都是这些内置对象的实例,BOM,DOM也是对象,全局变量可以视为window的属性。
学习JavaScript,最重要的就是理解对象这个概念,因为我们所有的语句,处理的都是对象。
在ECMAScript的概念中,对象被定义为:无序属性的集合,器属性可以包含基本值,对象,或函数。
所有的函数应该是方法,如果函数不是开发者创建的对象的属性,那它就是window的属性。
二、对象的创建
创建对象的模式包括:工厂模式、构造函数模式、原型模式、组合模式、动态原型模式、寄生构造函数模式和稳妥构造函数模式。
1、工厂模式
许多面向对象语言都使用类来创建对像,在JavaScript中,并没有类的定义。JavaScript中的工厂模式将创建对象的细节封装在一个函数中,当需要创建一个对象时,需要调用此函数。
function createObject(property1,property2,property3){ var aObject = new Object(); aObject.property1 = property1; aObject.property2 = property2; aObject.property3 = property3; aObject.method1 = function(){ do something; }; return aObject; }
工厂模式的问题在于它没有解决对象识别的问题(怎样识别一个对象)。
2、构造函数模式
构造函数模式的思路在于考虑到函数本身也是一个对象,而且函数没有重载的特性,所以可以使用函数内部的this对象,来为创建对象的函数添加属性和方法,使构造函数成为我们想要的对象。
function AObject(property1,property2,property3){ this.property1 = property1; this.property2 = property2; this.property3 = property3; this.method1 = function(){ do something... ; }; }
构造函数模式的问题在于每一次使用构造函数创建对象时,都会在后台自动创建相应的方法函数,当对象的方法很多时,后台会创建很多相同的函数,如果我们把方法函数取出到构造函数以外,由构造函数内部的方法去调用的话,又失去了函数的封装性。
3、原型模式
原型模式的原理是利用了函数对象的prototype属性,在JavaScript中,每一个对象都拥有一个prototype属性,这个属性指向了一个对象的原型,包含着this类型的所有对象实例所拥有的属性和方法
原型模式利用函数的prototype属性,创建了一个基于此构造函数的原型对象,每当我们调用此构造函数创建对象实例时,我们创建的对象实例都会从这个prototype创建的原型继承属性和方法。这样就解决了构造函数模式所面临的问题
function Person(){ Person.prototype.name = "wan"; Person.prototype.age = 14; Person.prototype.sayName = function(){ alert(this.name);}; } var person1 = new Person(); person.sayName();
我们也可以将Person.Prototype.name = "wan";等定义属性的语句放到函数以外,也可以使用字面量语法为原型添加属性和方法。
使用原型模式创建的对象实例,会重这个原型继承属性和方法,改写实例的属性,不会影响到原型和其它实例,创建一个同名属性,会覆盖继承来的属性,但不会影响原型和其它实例
原型模式的问题在于,如果一个属性是引用类型(比如数组),修改一个实例的属性会影响到其他实例和原型。
4、组合模式
组合模式集成了构造函数模式和原型模式的有点,是目前使用最广泛的创建对象模式。
在组合模式中,我们将对象实例私有的属性放在在构造函数中,将公共的属性和方法放在原型中,既满足了隐私性,又满足了性能上的要求
function AObejct(property1,property2,property3){ this.property1 = property1; this.property2 = property2; this.property3 = property3; } AObject.prototype.property4 = property4; AObject.prototype.method1 = function(){ do something... ; } var aObject = new AObject();
5、动态原型模式
组合模式的一个问题在于构造函数和原型分开了,动态原型将所有细节都封装到了一个函数中,通过一个if语句,检查一个对象是否已经拥有原型的方法,从而决定是否需要载入原型。
6、寄生构造函数模式
寄生构造函数模式与工厂模式唯一的区别在于调用构造函数前使用了new 操作符
一般情况下,很少使用这种方法创建对象
7、稳妥构造函数模式
在对安全性要求较高的场合,可以使用问题构造函数模式构造稳妥对象,稳妥对象没有公共属性,其方法也不引用this值。
二、继承
在面向对象程序设计中国,继承表示一个对象获得另I有一个对象的属性和方法的过程
在JavaScript中,实现继承主要靠原型链。
原型链的思想:每一个对象都有一个prototype属性,这个属性都可以使用这个prototype属性创建一个原型对象,让另一个对象等于这个原型对象,成为原型的实例,实例便继承了原对象的属性和方法。而实例对象也可以利用自身的prototype属性创建一个原型,来让其它对象继承,如此形成了一条长长的继承链条,称为原型链。
使用原型链继承的方法:只要让需要继承的实例对象的prototype属性等于被继承对象的构造函数就行了。
如同创建对象时的原型模式一样,原型链也存在引用类型的问题,如果修改一个实例的引用类型属性,会影响到原型和其它实例。
2、借助构造函数
构造函数的思想是在子类型的构造函数内部调用超类型的构造函数,调用时要用到函数地 call()或apply()方法,这样每次创建函数时都会在函数作用域内调用超类型的构造函数
如同创建对象时的构造函数模式,这种继承方式也会产生性能上的问题。
3、组合继承
组合继承就是将私有的属性和引用类型的属性使用构造函数继承,将共有的属性和方法用原型链继承。这也是目前应用比较广泛的一种继承方式。
4、原型式继承
原型式继承如同创建对象的工厂模式,它将继承的过程封装在一个函数中,在这个函数中,实现了对象的浅复制,这种方式适用于创建大量相似的对象而且无需考虑性能的环境。
5、寄生式继承
寄生继承模式是与原型式继承紧密相关的一种继承方式,它在使用原型式继承的基础上重写了对象的方法来增强对象。
6、寄生组合式继承
组合继承模式在继承过程中调用了2次超类型的构造函数,在某些场合不符合性能上的要求,于是寄生组合模式出现了,这种模式将寄生式继承的继承方式封装在一个继承函数中,使用子类型对象和超类型对象作为参数,继承的过程就只需调用一次继承函数。
本文出自 “wanghaz的学习” 博客,请务必保留此出处http://10703847.blog.51cto.com/10693847/1698330
标签:javascript
原文地址:http://10703847.blog.51cto.com/10693847/1698330