JavaScript高级程序设计学习笔记--面向对象程序设计
工厂模式
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用
工厂模式的一种变体。
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("Grey",27,"Doctor");
函数createPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象。可以无数次的调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
构造函数模式
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");
var person2=new Person("Grey",27,"Doctor");
在这个例子中,Person()函数取代了createPerson函数。我们注意到,Person()中的代码除了与createPerson()中相同的部分外,还存在以下不同之处:
(1):没有显式的创建对象;
(2):直接将属性和方法赋给了this对象;
(3):没有return语句
原型模式
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
function Person(){
} Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.sayName=function(){
alert(this.name);
} var person1=new Person();
person1.sayName(); //"Nicholas" var person2=new Person();
person2.sayName(); //"Nicholas" alert(person1.sayName==person2.sayName); //true
虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加一个属性,而该属性与实例原型中的一个属性同名,那我们就在实例
中创建该属性,该属性将会屏蔽原型中的属性。
原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何个修改都能够立即从实例上反映出来--即使先创建了实例后个性原型也照样如此。请看下面的例子:
var friend=new Person();
Person.prototype.sayHi=function(){
alert("HI");
}
friend.sayHi(); //"HI" (没有问题!)
以上代码先创建了Person的一个实例,并将其保存在person中,然后,下一条语句在Person.prototype中添加了一个方法sayHi().即使person实例是在添加新方法之前创建的,
但它仍然可以访问这个新方法。
尽管可以随时为原型添加属性和方法,并且个性能够立即在所有对象实例中反映出来,但如果是重写整个原型对象,那么情况就不一样了。我们知道,调用构造函数时会为实例
添加一个指向最初原型的[[Prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。请记住:实例中的指针仅指向原型,而不指向构造
函数。看下面的例子:
function Person(){
}
var friend=new Person(); Person.prototype={
constructor:Person,
name:"Nicholas",
age:29,
job:"Software Engineer",
sayName:function(){
alert(this.name);
}
};
friend.sayName(); //error
动态原型模式
可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。来看下面一个例子:
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);
}
}
}
var friend=new Person("Nicholas",29,"Software Engineer");
friend.sayName();
寄生构造函数模式
通常,在前述几种模式都不适用的情况下,可以使用寄生(parasitic)构造函数模式。这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回
新创建的对象;但从表面上看,这个函数又很像是典型的构造函数。下面是一个例子:
function Person(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 friend=new Person("Nicholas",29,"Software Engineer");
friend.sayName(); //"Nicholas"
在这个例子中,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。
这个模式可以在特殊情况下用来为对象创建构造函数。假设我们想创建一个具有额外方法的特殊数组。由于不能直接修改Array构造函数,因此可以使用这个模式。
function SpeicalArray(){
var values=new Array(); //创建数组
values.push.apply(values,arguments); //添加值
values.toPipedString=function(){
return this.join("|");
}
return values; //返回数组
}
var colors=new SpeicalArray("red","blue","green");
alert(colors.toPipedString()); //"red|blue|green"
JavaScript高级程序设计学习笔记--面向对象程序设计的更多相关文章
- JavaScript高级程序设计学习笔记--面向对象的程序设计(二)-- 继承
相关文章: 面向对象的程序设计(一) — 创建对象 http://www.cnblogs.com/blackwood/archive/2013/04/24/3039523.html 继承 继承是OO语 ...
- Javascript高级编程学习笔记(18)—— 引用类型(7)单体内置对象
什么是内置对象呢? js高级程序设计中给出的定义为:由ES规定不依赖于宿主环境的对象,这些对象在JS执行前就已经存在 前面我们介绍的引用类型都是内置对象 除了这些对象外ECMA还规定了两个单体内置对象 ...
- Javascript高级编程学习笔记(10)—— 作用域、作用域链
昨天介绍了,JS中函数的作用域 什么词法环境之类的,可能很多小伙伴不太明白. 在今天的内容开始之前,先做个简短的声明: 词法环境这一概念是在ES5中提出的,因为词法环境主要用于保存let.const声 ...
- Javascript高级编程学习笔记(3)—— JS中的数据类型(1)
前一段时间由于事情比较多,所以笔记耽搁了一段时间,从这一篇开始我会尽快写完这个系列. 文章中有什么不足之处,还望各位大佬指出. JS中的数据类型 上一篇中我写了有关JS引入的Script标签相关的东西 ...
- JavaScript高级编程学习笔记(第三章之一)
继续记笔记,JavaScript越来越有意思了. 继续... 第三章:JavaScript基础 ECMAScript语法在很大程度上借鉴了C和其它类似于C的语言,比如Java和Perl. 大小写敏感: ...
- Javascript高级编程学习笔记(98)—— WebGL(4) WebGL上下文(2)
错误 Javascript与WebGL之间的一个最大区别在于,WebGL的操作一般不会抛出错误 如果希望获取WebGL的错误信息,那么就需要手动调用 gl.getError() 方法 该方法会返回以 ...
- Javascript高级编程学习笔记(97)—— WebGL(3) WebGL上下文(1)
WebGL上下文 在支持WebGL的浏览器中,WebGL的名字为 "experimental-webgl",这是由于 webgl 的规范仍未制定完成 制定完成后名字就会改为简单的 ...
- Javascript高级编程学习笔记(96)—— WebGL(2) 类型化视图
类型化视图 类型化视图一般也被认为是一种类型化数组. 因为其元素必须是某种特定的数据类型,类型化视图都继承自 Dataview Int8Array: 表示8位二补整数(即二进制补数) Uint8Arr ...
- Javascript高级编程学习笔记(1)—— JS简介
此系列文章,用于记录所学,如有错误欢迎指出. Javascript组成 1.核心(ECMAScript) 2.文档对象模型(DOM) 3.浏览器对象模型(BOM) 1.核心(ECMAScript) E ...
随机推荐
- QT文件读写
/* //文件读取 QFile f("c:\\t.txt"); if(!f.open(QIODevice::WriteOnly | QIODevice::Text)) { qDeb ...
- oracle数据库启动
遇到个白痴问题,放假停电,回来时启动数据库,发现无法进入oracle管理员界面. 如下输入,但是显示的命令无效. [oracle@crm001 database]$ sqlplus / as sysd ...
- OS X 10.10.5编译Android5.1.1源码
--------------------------------------------------写在前面---------------------------------------------- ...
- php:获取浏览器的版本信息
//分析返回用户网页浏览器名称,返回的数组第一个为浏览器名称,第二个是版本号. function getBrowser() { $sys = $_SERVER['HTTP_USER_AGE ...
- docker镜象
1.安装好docker后,用docker命令的时候有时候会报错:Post http:///var/run/docker.sock/v1.19/images/create?fromImage=ubunt ...
- MongoDB的索引(三)
MongoDB的索引: 1. _id索引 该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段. 2. 单键索引 单键索引是最普通的索引,它不会自 ...
- python 环境安装
wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz tar zxf Python-2.7.3.tgz cd Python-2. ...
- [转载]PO BO VO DTO POJO DAO概念及其作用
原文链接:http://jeoff.blog.51cto.com/186264/88517/ POJO = pure old java object or plain ordinary java ob ...
- SMTP协议--在cmd下利用bat命令行发送邮件
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议 选择‘开始’-‘运行’,输入cmd,进入命令提示符窗口. Windows7默认没有开始Telnet服务,请在运 ...
- HDU 1423 最长公共字串+上升子序列
http://acm.hdu.edu.cn/showproblem.php?pid=1423 在前一道题的基础上多了一次筛选 要选出一个最长的递增数列 lower_bound()函数很好用,二分搜索找 ...