1.工厂模式

工厂模式是一种常用的创建对象的模式,可以使用以下函数封装创建对象的细节:

function CreatePerson(name,age){
var p=new Object();
p.name=name;
p.age=age;
p.speak=function(){
console.log("my name is "+p.name);
}
return p;
} var p1=CreatePerson('Wang',15);
p1.speak(); var p2=CreatePerson("Li",18);
p2.speak();

特点:工厂模式实现了创建相似对象的功能,但是缺点是无法确定所创建出来对象的类型。

2.构造函数

①使用构造函数可以创建对象:

function Person(name,age){
this.name=name;
this.age=age;
this.speak=function(){
console.log("my name is "+this.name);
}
}

构造函数和工厂模式区别的地方:没有在函数内显式的创建对象,而是直接将属性赋值给this;没有使用return语句返回。

②调用:使用new操作符调用构造函数创建对象。

//作为构造函数调用
var p1=new Person('Wang',15);
p1.speak();// my name is Wang
var p2=new Person("Li",18);
p2.speak();// my name is Li

调用过程经历了几个步骤:

  • 创建一个新对象;
  • 将构造函数的作用域赋给该对象,此时this也就指向了该对象;
  • 执行构造函数中的代码;
  • 返回该对象。

另外,构造函数也可以作为普通函数调用,此时this指向的是window对象:

Person('chen',15);
window.speak();//my name is chen

③调用构造函数创建的对象,既是Person的实例,也是Object的实例。这一点上比工厂模式略胜一筹。

console.log(p1 instanceof Object);//true
console.log(p1 instanceof Person);//true

④缺点:方法speak要在每个实例上都创建一遍,不能进行共享。

p1.speak==p2.speak;//返回false

3.原型模式

使用原型对象prototype的好处是可以让所有对象实例共享它所包含的属性和方法。

function Person(){
} //原型
Person.protype={
constructor:Person,
name:'Tom',
age:18,
speak:function(){
console.log('my name is '+this.name+',I am '+this.age);
}
} //调用
var p1=new Person();
var p2=new Person();
console.log(p1.speak==p2.speak);//true
console.log(p1.speak());//my name is Tom,I am 18

可以看出Person的实例对象共享了属性和方法。

isPrototypeOf()方法用来检测实例和原型对象之间的关系。

console.log(Person.prototype.isPrototypeOf(p1));//true

当给实例设置与原型中同名的属性时,会给该实例对象新增一个属性,它会屏蔽访问原型中的同名属性值但不会修改原型中的属性值。

p1.name='Cathy';
console.log(p1.name);//Cathy
console.log(p2.name);//Tom

如果想重新访问原型中的属性值,可以使用delete操作符删除实例属性即可。

delete p1.name;
console.log(p1.name);//Tom
console.log(p2.name);//Tom

hasOwnProperty()方法:用来检测某属性是存在于实例中还是存在于原型中。仅当属性存在于实例中时,才返回true。

in 操作符:只要对象存在某属性就返回true,无论是实例属性还是原型属性。

p1.hasOwnProperty('name')//false
"name" in p1;//true
p1.name='Cathy';
p1.hasOwnProperty('name')//true
"name" in p1;//true
p2.hasOwnProperty('name')//false
"name" in p2;//true
delete p1.name;
p1.hasOwnProperty('name')//false
"name" in p1;//true

结合使用hasOwnProperty和in,可以判断属性是不是存在于原型中。

function hasPrototypeProperty(object,name){
return (!object.hasOwnProperty(name))&&(name in object);
}
var p1=new Person();
console.log(hasPrototypeProperty(p1,'name'));//true
p1.name='Peter';
console.log(hasPrototypeProperty(p1,'name'));//false

原型的动态性:对原型所做的修改能够立即从实例中体现出来。

function Person(){
}
var p=new Person();
Person.prototype.speak=function(){
console.log("hello world");
}
p.speak();//hello world

原型模式缺点:实例之间共享所有的原型属性和方法,有些个性化的属性无法体现。

4. * 组合使用构造函数模式和原型模式

这种组合是最常见的一种方式,用构造函数模式创建实例属性,原型模式定义公用的属性和方法。

function Person(name,age)
{
this.name=name;
this.age=age;
this.friends=['lucy','kate']
}
Person.prototype={
constructor:Person,
sayName:function(){
console.log("my name is "+this.name);
}
}
var p1=new Person('Ken',16);
p1.sayName();//my name is Ken
var p2=new Person('Peter',20);
p2.sayName();//my name is Peter
p1.friends.push('Zhang');
console.log(p1.friends);// ["lucy", "kate", "Zhang"]
console.log(p2.friends);// ["lucy", "kate"]

5.动态原型模式

function Person(name,age)
{
this.name=name;
this.age=age;
if(typeof this.sayName!='function'){
Person.prototype.sayName=function(){
console.log("my name is "+this.name);
}
}
}
var p1=new Person('Ken',16);
p1.sayName();//my name is Ken
var p2=new Person('Peter',20);
p2.sayName();//my name is Peter

说明:不必检查原型中的每个属性和方法,只要检查其中一个即可;

不能使用对象字面量方法重写原型。

读javascript高级程序设计05-面向对象之创建对象的更多相关文章

  1. 读javascript高级程序设计00-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  2. 读javascript高级程序设计-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  3. 读javascript高级程序设计08-引用类型之Global、Math、String

    一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...

  4. 读Javascript高级程序设计第三版第六章面向对象设计--创建对象

    虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码. 工厂模式  1 function CreatePerson(name,a ...

  5. 读javascript高级程序设计07-引用类型、Object、Array

    一.引用类型 ECMAScript是支持面向对象的,可以通过引用类型描述一类对象所具有的属性和方法. 创建对象实例的方法时是用new 操作符加构造函数:var p=new Person(). 二.Ob ...

  6. 读javascript高级程序设计10-DOM

    一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...

  7. 读javascript高级程序设计15-Ajax,CORS,JSONP,Img Ping

    平时用惯了jQuery.ajax之类的方法,却时常忽略了它背后的实现,本文是学习了AJAX基础及几种跨域解决方案之后的一些收获. 一.AJAX——XMLHttpRequest 谈起Ajax我们都很熟悉 ...

  8. 《JavaScript高级程序设计》读书笔记 ---创建对象

    虽然Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为解决这个问题,人们开始使用工厂模式的一种变体. 工厂模式工厂 ...

  9. 读javascript高级程序设计17-在线检测,cookie,子cookie

    一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...

随机推荐

  1. HTTP下载文件名称编码说明

    HTTP下载保存文件名 下载文件需要保存的名称 在响应报文头中 Content-Disposition 响应报文头域中指定, 例如 Content-Disposition: attachment; f ...

  2. (一)keil4 MDK 开发环境下编写裸机程序 (参考杨铸 北航) (开发板只需要连接JLNK 就行了)

    首先用的是 keil4  位与   ( F:\ARM+LINUX\MDK-ARM_v4.10.exe  ) 1. 新建工程名project 为    led circle   ,放在  我的文档\ l ...

  3. Maps for Developers

    苹果官方文档: Give your apps a sense of place with maps and location information. Present maps with custom ...

  4. Git Permission denied (publickey).

    有可能, jenkins slave service or jenkins service的logon 账户没有设置好

  5. s3c2440 移值u-boot-2016.03 第4篇 支持NAND flash 识别

    1, /include/configs/smdk2440.h 中添加 #define CONFIG_CMD_NAND 编译 drivers/mtd/nand/built-in.o: In functi ...

  6. RecycleView可以策划的Item

    public abstract class SwipeMenuViewHolder { /* 从左侧滑出菜单 */ public static final int EDGE_LEFT = 1; /* ...

  7. NET中的类型和装箱/拆箱原理

    谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...

  8. WIFI驱动的移植 realtek 8188

    一般我们拿到的android源代码中wifi应用层部分是好的, 主要是wifi芯片的驱动要移植并添加进去. wifi驱动的移植, 以realtek的8188etv为例到官网下载相应的驱动, 解压后可以 ...

  9. 查看oracle被锁的表

    SELECT /*+ rule*/ a.sid, b.owner, object_name, object_type FROM v$lock a, all_objects b WHERE TYPE = ...

  10. asp.net 之 购物车

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...