精读《javascript高级程序设计》笔记三——面向对象的程序设计
重点来了,我认为这一章值得好好地反复地看。看第一遍 还是懵懵懂懂,现在看第二遍,终于能看出点意思了。
创建对象
- 工厂模式
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
} var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");优点:解决了Object构造函数或对象字面量创建多个对象代码重复的问题
缺点:无法识别对象.
- 构造函数模式:
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
alert(person1.constructor == Person);
alert(person1 instanceof Object);
alert(person1 instanceof Person);优点:可以将它的实例识别为一种特定的对象
缺点:每个方法都要在每个实例上重新创建一遍,增加不必要的内存开支
- 原型模式
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); var person2 = new Person();
person2.sayName();
alert(person1.sayName === person2.sayName);原型模式创建的属性对象是由所有实例共享的。
缺点:原型模式在包含引用类型时,实例共享会引起比较严重的问题。
在所有实现中都无法直接访问到prototype,只通通过isPrototypeOf()来检验对象之间是否存在这种关系。例:Person.prototype.isPrototypeOf(person1)
在实例中添加一个与原型中的同名属性,会在实例中创建该属性,而不会改变原型的值
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person2.name); //"Nicholas"——来自原型hasOwnProperty()检测一个属性是否在实例中;in 检测是否能访问到访属性,可能是在实例中,也可能是在原型中;
/*检测属性是否存在于原型中*/
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}更简单的原型:
function Person(){
}
Person.prototype = {
constructor : Person,
/*用字面量定义prototype时,要设置它的constructor,不然它的constructor会指向Object*/
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function (){
alert(this.name);
}
};
/*这样设置有一点不足,会使constructor变为可枚举的,如果是支持ECMAScript5的浏览器,可用Object.defineProperty()是方法来设置constructor*/
/*Object.defineProperty(Person.prototype, "constructor",{
enumerable:false,
value:Person
});*/实例中的指针仅指向原型,而不指向构造函数
- 组合使用构造函数模式和原型模式
构造函数模式用于定义实例属性,原型模式用于定义方法和共享属性。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby","Court"];
} Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
} - 动态原型模式
把所有信息封装到构造函数中,在构造函数中初始化原型。
优点:解决了独立的构造函数模式和原型模式独立的问题,又同时保持了两者的优点。
使用这种方法创建对象,不能用对象字面量重字原型。
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
//方法
if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
};
}
} - 寄生构造函数模式
除了用new操作符并把使用的包装函数叫做构造函数外,这个方法与工厂模式是一样的
例:具有额外方法的特殊数组,不又直接修改Array的构造函数function SpecialArray(){
//创建数组
var values = new Array(); //添加值
values.push.apply(values, arguments); //添加方法
values.toPipedString = function(){
return this.join("|");
}; return values;
}
var colors = new SpecialArray("red","blue","green");
alert(colors.toPipedString());使用这种模式,建议不要与其他模式混用
继承
- 通常说的继承有接口继承和实现继承,由于js无方法签名,所以不支持接口继承。只通过原型链实现了实现继承。
- 原型链
实现方法:SubType.prototype = new SuperType();
注1:子类型需要重写超类方法或添加超类中不存在的方法,需要在实现继承语句之后,这样才能屏蔽超类方法
注2:在通过原型链实现继承时,不能使用对象字面量方法创建原型方法,因为这样做会重写原型链
- 借用构造函数(伪造对象/经典继承)
在子类型构造函数的内部调用超类型构造函数SuperType.call(this);
比原型链继承的优点是,解决了实例共享的问题,并可以传递参数
缺点同实例相同,也具有方法不能共享的问题
- 组合模式
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
}; function SubType(name, age){
SuperType.call(this,name); this.age = age;
} SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){
alert(this.age);
}; var instance1 = new SubType("Nicholas",29);
instance1.colors.push("black");
alert(instance1.colors);
instance1.sayName();
instance1.sayAge(); var instance2 = new SubType("Greg",27);
alert(instance2.colors);
instance2.sayName();
instance2.sayAge(); - 原型式继承
function object(o){
function F(){}
F.prototype = o;
return new F();
}实现对传入对象o的浅复制,IE9+的Object.create(o)有相似功能
精读《javascript高级程序设计》笔记三——面向对象的程序设计的更多相关文章
- javascript高级编程笔记05(面向对象)
面向对象设计 es中有两种属性:数据属性和访问器属性 数据属性: 数据属性包含一个数据值的位置,在这个位置可以读取和写入值,数据属性有4个描述其行为的特性 [[Configurable]]:表示能否通 ...
- Javascript基础回顾 之(三) 面向对象
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
- javascript高级编程笔记01(基本概念)
1.在html中使用JavaScript 1. <script> 元素 <script>定义了下列6个属性: async:可选,异步下载外部脚本文件. charset:可选, ...
- 《JavaScript高级程序设计》笔记:面向对象的程序设计(六)
面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象. 理解对象 创建自定义对象的最简单的方法就是创建一个Object的实例,然后再为它添加属性和方法.例 ...
- JavaScript高级程序设计笔记之面向对象
说起面向对象,大部分程序员首先会想到 类 .通过类可以创建许多具有共同属性以及方法的实例或者说对象.但是JavaScript并没有类的概念,而且在JavaScript中几乎一切皆对象,问题来了,Jav ...
- javascript 高级程序设计学习笔记(面向对象的程序设计) 1
Object构造函数或对象字面量都可以用来创建对象,但这些方式有个明显的缺点:使用相同一个接口创建很多对象,会产生大量重复代码. 工厂模式 //工厂模式 function createDog (nam ...
- javascript 高级程序设计学习笔记(面向对象的程序设计)继承
ECMAScript中描述了原型链的概念,原型链是实现继承的主要方法. 实现原型链继承有一种基本模式 function SuperType () { this.property = true; } S ...
- javascript 高级程序设计学习笔记(面向对象的程序设计) 2
在调用构造函数时会为实例添加一个指向最初原型的指针,我们可以随时为原型添加属性和方法,并且能在实例中体现出来,但如果是重新了原型对象,那就会切断构造函数与最初原型的联系. function Dog ( ...
- 《JAVASCRIPT 高级程序设计》读书笔记六 面向对象的程序设计
一 对象属性 a.对象定义: 无序属性的集合,其属性可以包含基本值.对象或者函数: b.两种创建方式: 1.构造函数: var person = new Object(); person.name ...
随机推荐
- HTML 基础 2
1. 认识CSS样式: CSS:层叠样式表(Cascading Style Sheets),主要用于定义HTML内容在浏览器内的显示样式 语法: 选择符{ 属性: 值} 举例: p{ color: b ...
- 从头开始-04.C语言中流程控制
分支结构: if语句:当条表达式满足的时候就执行if后面大括号中语句 三种格式: if,if else , if else if else 特点:1.只有一个代码块会被执行 2.若有else那么必有一 ...
- C#VS面向对象基础(二)
这里我们接着上一篇博客,继续学习用C#实现面向对象中的概念.这里学习下边几个,当然我们还是通过动物比赛的例子. 多态:表示不同的对象可以执行相同的动作,但是通过它们自己的实现代码来执行.这里需要将父类 ...
- JQuery弹出层,点击按钮后弹出遮罩层,有关闭按钮
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- matlab求方差,均值,均方差,协方差的函数
1. 均值 数学定义: Matlab函数:mean >>X=[1,2,3] >>mean(X)=2 如果X是一个矩阵,则其均值是一个向量组.mean(X,1)为列向量的均值,m ...
- js选项卡切换效果
选项卡切换在页面中比较常见,这里是我利用js闭包还有setTimeout定时器实现的一个比较实用的选项卡功能. <!DOCTYPE html> <html lang="en ...
- jQuery学习-事件之绑定事件(六)
在jQuery中,为了屏蔽event对象在各浏览器中的差异性,它使用了自定的Event对象,如下: 1 jQuery.Event = function( src, props ) { 2 ...
- Flex中如何通过horizontalTickAligned和verticalTickAligned样式指定线图LineChart横竖方向轴心标记的例子
原文http://blog.minidx.com/2008/12/03/1669.html 接下来的例子演示了Flex中如何通过horizontalTickAligned和verticalTickAl ...
- 元素“Button”不是已知元素。原因可能是网站中存在编译错误,或者缺少web.config文件
最近开发的时候ASP控件都有波浪下划线,提示不是已知元素,搞得挺郁闷的.虽然不影响变异,不过就是不爽. 折腾N久...... 解决了,把FramWork平台换成3.5,问题解决,不知道为啥,求大神指点 ...
- 并查集及其简单应用:优化kruskal算法
并查集是一种可以在较短的时间内进行集合的查找与合并的树形数据结构 每次合并只需将两棵树的根合并即可 通过路径压缩减小每颗树的深度可以使查找祖先的速度加快不少 代码如下: int getfather(i ...