读Javascript高级程序设计第三版第六章面向对象设计--创建对象
虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码。
工厂模式
1 function CreatePerson(name,age,job){
2 var o=new Object();
3 o.name=name;
4 o.age=age;
5 o.job=job;
6 o.sayName=function(){
7 alert(this.name);
8 }
9 return o;
10 }
11 var person1=CreatePerson("Jim",29,"Teaching in Colleage");
12 var person2=CreatePerson("Merry",23,"Study in Colleage");
13 console.log(person1.sayName==person2.sayName);
解决了创建多个对象的问题,但是却没有解决对象识别的问题。
构造函数模式
1 // 构造函数模式
2 /*
3 必须使用 new 操作符,会经过以下几个步骤
4 1 创建一个新对象
5 2 将构造函数的作用域赋值给新对象
6 3 执行构造函数中的代码(为新对象添加属性)
7 4 返回新对象
8 */
9 function PersonByConstructor(name,age,job){//按照惯例构造函数以大写字母开头
10 this.name=name;
11 this.age=age;
12 this.job=job;
13 this.sayName=function(){
14 alert(this.name);
15 };
16 }
17 var person3=new PersonByConstructor("John",24,"Software Engineer");
18 var person4=new PersonByConstructor("Greg",25,"Doctor");
19
20 console.log(person3 instanceof PersonByConstructor);//返回true
21 console.log(person4 instanceof PersonByConstructor);
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型。
任何函数,只要通过new 操作符来调用,那它就可以作为构造函数;否则和普通函数一样。
1 PersonByConstructor("Lily",32,"Driver");//添加到window
2 window.sayName();
3
4 var o=new Object();
5 PersonByConstructor.call(o,"Kristen",23,"Nurse");
6 o.sayName();
构造函数模式虽然好用,但是每个方法都要在每个实例上重新创建一遍。
可以将方法移到构造函数的外部解决,但是如对象要调用很多方法,则需要定义很多全局函数,这样就没有封装性可言了。这个问题可以通过原型模式来解决。
原型模式
我们创建的每一个函数都有原型属性(prototype),这个属性是一个指向对象的指针,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用对象原型的好处是让所有对象实例共享它所包含的属性和方法。
理解原型对象
无论什么时候,只要创建一个对象,都会根据一定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下所有原型都会自动获取一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
function PersonByPrototype(){
}
PersonByPrototype.prototype={
name:"Jim",
age:21,
job:"Teaching",
sayName:function(){
console.log(this.name);
}
}
var person5=new PersonByPrototype();
person5.sayName();
var person6= new PersonByPrototype("Mick",32,"assitant");
person6.sayName();
console.log(PersonByPrototype.prototype.isPrototypeOf(person5));//通过 prototype.isPrototypeOf 来确定PersonByPrototype是否是person5的原型
console.log(Object.getPrototypeOf(person5).name);//Object.getPrototypeOf可以方便的获取对象的原型,这在利用原型实现继承的情况下是非常重要的
每当代码读取某个对象的属性时,都会指向一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始,如果找到则返回该属性的值,如果没找到,则搜索指针指向原型对象,在原型对象查找具有给定名字的属性。我们对原型的修改会立刻的体现出来。
当为对象实例添加新的属性时,这个属性就会屏蔽 原型对象 中的那个同名属性,换句话说,会阻止我们访问原型中的属性,但不会修改那个属性。不过使用delete可以删除实例中的属性,从而使我们能够访问原型中的属性。
console.log(person6.hasOwnProperty("name")); //hasOwnProperty 来判断属性是实例的还是原型继承来的
console.log(person5.hasOwnProperty("name"));
原型与 IN 操作符
在单独使用时,in 操作符会在通过对象能够访问给定属性时返回 true,无论该属性存在于实例中还是原型中。只要 in 操作符返回 true, 而 hasOwnProperty返回false,就可以确定属性是原型中的属性。
function hasPrototypeProperty(name,obj){
return !obj.hasOwnProperty("name") && ("name" in obj);
}
在使用 for-in 循环时,返回的是通过对象访问的、可枚举的属性,其中包括实例和原型对象中的属性。
for (var prop in person5)
console.log(prop); //返回 name,age ,job, sayName
原型的动态性
实例中的指针仅指向原型,而不是构造函数。
如果把原型改为另外一个对象,相当于切断了构造函数和最初原先对象之间的联系。
原生对象的问题
1 省略了为构造函数传参这一环节
2 原型中所有属性都是被所有实例共享的。
组合使用原型模式和构造函数模式
构造函数模式用于定义实例属性,原型模式来定义方法和共享的属性。
function PersonByConstructorAndPrototype(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=[];
}
PersonByConstructorAndPrototype.prototype={
constructor:PersonByConstructorAndPrototype,
sayName:function(){console.log(this.name);}
} var person7=new PersonByConstructorAndPrototype("LiLei",12,"Student");
var person8 = new PersonByConstructorAndPrototype("LiuLei",13,"Student")
person7.friends.push("LiuLei");
person8.friends.push("LiLei");
console.log(person7.friends.toString());
console.log(person8.friends);
动态原型模式
有其他 OO 语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑。动态原型模式正是致力于解决这个问题的一个方案,它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的优点。换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。
寄生构造函数模式
如果上面几种方式都不适用,可以适用寄生模式。该模式的核心思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码。
//寄生构造函数模式
function PersonByParasitic(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
console.log(this.name);
};
return o;
} var friend=new PersonByParasitic("Nicholas",20,"Software Engineer");
friend.sayName();
var friend2=new PersonByParasitic("Nick",32,"");
friend2.sayName();
这个模式可以在特殊情况下为对象创建构造函数。
稳妥构造函数模式
稳妥对象指的是没有公共属性,而其方法也不引用this对象。
读Javascript高级程序设计第三版第六章面向对象设计--创建对象的更多相关文章
- javascript高级程序设计第3版——第6章 面向对象的程序设计
第六章——面向对象的程序设计 这一章主要讲述了:面向对象的语言由于没有类/接口情况下工作的几种模式以及面向对象语言的继承: 模式:工厂模式,构造函数模式,原型模式 继承:原型式继承,寄生式继承,以及寄 ...
- JavaScript高级程序设计第三版.CHM【带实例】
从驱动全球商业.贸易及管理领域不计其数的复杂应用程序的角度来看,说 JavaScript 已经成为当今世界上最流行的编程语言一点儿都不为过. JavaScript 是一种非常松散的面向对象语言,也是 ...
- Javascript高级程序设计读书笔记(第六章)
第6章 面向对象的程序设计 6.2 创建对象 创建某个类的实例,必须使用new操作符调用构造函数会经历以下四个步骤: 创建一个新对象: 将构造函数的作用域赋给新对象: 执行构造函数中的代码: 返回新 ...
- javascript高级程序设计第三版书摘
在HTML 中使用JavaScript <script>元素 在使用<script>元素嵌入 JavaScript 代码时,只须为<script>指定 type 属 ...
- 22.1 高级函数【JavaScript高级程序设计第三版】
函数是JavaScript 中最有趣的部分之一.它们本质上是十分简单和过程化的,但也可以是非常复杂和动态的.一些额外的功能可以通过使用闭包来实现.此外,由于所有的函数都是对象,所以使用函数指针非常简单 ...
- JavaScript高级程序设计第三版-读书笔记(1-3章)
这是我第一次用markdown,也是我第一次在网上记录我自己的学习过程. 第一章 JavaScript主要由以下三个不同的部分构成 ECMAScript 提供核心语言功能 DOM 提供访问 ...
- 21.1 XMLHttpRequest 对象【JavaScript高级程序设计第三版】
IE5 是第一款引入XHR 对象的浏览器.在IE5 中,XHR 对象是通过MSXML 库中的一个ActiveX对象实现的.因此,在IE 中可能会遇到三种不同版本的XHR 对象,即MSXML2.XMLH ...
- 《JavaScript高级程序设计第三版》——细碎知识痛点整理(第六章)
面向对象的程序设计 对象是一组没有特定顺序的值6.1.1 属性类型ECMAScript中有两种属性:数据属性和访问器属性.1. 数据属性Configurable 表示能否通过delete删除属性从而重 ...
- 14.5 富文本编辑【JavaScript高级程序设计第三版】
富文本编辑,又称为WYSIWYG(What You See Is What You Get,所见即所得).在网页中编辑富文本内容,是人们对Web 应用程序最大的期待之一.虽然也没有规范,但在IE 最早 ...
随机推荐
- mfc release 版本 内存不足 的解决方法
- C#矩阵运算类库
这个类库是本人参考许多相关资料之后做出的C#矩阵运算类库,因为C#的数值计算库相对比较少,所以希望这个类库能够给大家带来一些帮助. 源码github网址:https://github.com/Josh ...
- win7 audio repeater 虚拟声卡 屏幕录像专家
- 检测Linux VPS是Xen、OpenVZ还是KVM真假方法
如果大家对自己购买和使用的VPS需要检测是否为真的Xen,我们可以用如下方法进行测试.比较专业的就是用virt-what脚本进行检测.检测Linux VPS是Xen.OpenVZ还是KVM真假方法方法 ...
- XCodeGhost 笔记
因为服务已经关掉了,所以要改路由Openwrt vi /etc/config/dhcp vi /etc/dnsmasq/dnsmasq.conf /etc/init.d/dnsmasq restart ...
- win7、linux安装使用pip、mitmproxy
安装pip https://pip.pypa.io/en/latest/installing.html 步骤: 下载 https://bootstrap.pypa.io/get-pip.py pyth ...
- ADC测试matlab代码
前面有做过ADC性能测试,测试方式是先使用ADC采集一个单频信号,然后利用matlab进行性能分析. 下面把matlab分析的代码记录下来: %The following program code p ...
- 查找SQL SERVER被锁的表和解决方法
查找数据库中被锁表代码: select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName ...
- 关于计算机的ID和用户ID之间的关系
关于计算机的ID和用户ID之间的关系 计算机安装完系统后就会生成计算机ID,然后系统会以计算机ID为前缀附加数字创建Administrator(500)和Guest(501)用户ID,其他用户的ID将 ...
- 块状元素(div)与内联元素(span)
<pre class="html" name="code"><html xmlns="http://www.w3.org/1999/ ...