读javascript高级程序设计05-面向对象之创建对象
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-面向对象之创建对象的更多相关文章
- 读javascript高级程序设计00-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计-目录
javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...
- 读javascript高级程序设计08-引用类型之Global、Math、String
一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...
- 读Javascript高级程序设计第三版第六章面向对象设计--创建对象
虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码. 工厂模式 1 function CreatePerson(name,a ...
- 读javascript高级程序设计07-引用类型、Object、Array
一.引用类型 ECMAScript是支持面向对象的,可以通过引用类型描述一类对象所具有的属性和方法. 创建对象实例的方法时是用new 操作符加构造函数:var p=new Person(). 二.Ob ...
- 读javascript高级程序设计10-DOM
一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...
- 读javascript高级程序设计15-Ajax,CORS,JSONP,Img Ping
平时用惯了jQuery.ajax之类的方法,却时常忽略了它背后的实现,本文是学习了AJAX基础及几种跨域解决方案之后的一些收获. 一.AJAX——XMLHttpRequest 谈起Ajax我们都很熟悉 ...
- 《JavaScript高级程序设计》读书笔记 ---创建对象
虽然Object 构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为解决这个问题,人们开始使用工厂模式的一种变体. 工厂模式工厂 ...
- 读javascript高级程序设计17-在线检测,cookie,子cookie
一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...
随机推荐
- 一种构造WEB服务器端recv和send接口阻塞现象的方法
send阻塞 socket recv send接口阻塞,会导致服务器端不在响应客户端任何请求,所以一般情况, 会将socket设置为非阻塞状态, 但是有些场景,例如ssl_accept就需要使用阻塞的 ...
- delphi关闭程序Close,application.Terminate与halt区别
当Close是一个主窗体时,程序会退出.Close会发生FormClose事件,FormCloseQuery事件Halt会发生FormDestory事件,Application.Terminate以上 ...
- Oracle EBS R12 电子技术参考手册 - eTRM (电子文档)
http://etrm.oracle.com/pls/etrm/etrm_search.search
- Java基础之在窗口中绘图——渐变填充(GradientApplet 1)
Applet程序. import javax.swing.*; import java.awt.*; import java.awt.geom.*; @SuppressWarnings("s ...
- js 给样式添加随机颜色
下面提供了三种获取随机颜色值的方法 方法一: 创建一个颜色 HEX 值数组,然后随机抽取这个数组里6个值,组合生成颜色. function color1(){ var color = "&q ...
- C#扩展特性
今天跟同事讨论技术,无意发现的C#3.0的一个新特性,高手可以直接忽略. 这个特性叫扩展,我觉得非常的方便所以就记录下来了.以下是我的测试代码: public static class test { ...
- windows安装TortoiseGit详细使用教程
标签:tortoisegit 环境:win8.1 64bit 安装准备: 首先你得安装windows下的git msysgit1.9.5 别下载错,不习惯英文的朋友,也可以下个语言包] 一.安装图解: ...
- MySQL and Postgres command equivalents (mysql vs psql)
MySQL and Postgres command equivalents (mysql vs psql) 博客分类: Database From: http://blog.endpoint.c ...
- Python—模块
一.模块 模块,是用一堆代码实现了某个功能的代码集合,模块分为三种:自定义模块(自己定义).内置模块(python自带).开源模块 导入模块 (1).导入一个py文件,解释器解释该py文件 (2).导 ...
- [Android Studio] 按钮学习
Android Studio 按钮 1. 添加一个按钮 新建一个 Blank Project 之后, 在 activity_main.xml: 中添加一个按钮, 可以使用design 模式来添加,: ...