读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 ...
随机推荐
- [转] 基于MySQL的秒杀核心设计(减库存部分)-防超卖与高并发
商品详情页面的静态化,varnish加速,秒杀商品库独立部署服务器这种就略过不讲了.只讨论库存部分的优化 mysql配置层面的优化可以参考我的这篇文章 <关于mysql innodb引擎性能优化 ...
- SecureCRT工具配色方案
一.配色后的效果图 二.设置背景颜色 1.选项(Options)==>会话选项(Sessions options)==>终端(Terminal)==>仿真(Emulation) 2. ...
- Leetcode: Maximum XOR of Two Numbers in an Array
Given a non-empty array of numbers, a0, a1, a2, - , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- logstash5.x配置
logstash --help --可以通过此命令看到所有命令 -f, --path.config --配置文件路径 -e, --config.string --可直接运行的配置字符串 -w, --p ...
- Mac下安装LNMP(Nginx+PHP5.6)环境
[转自:http://avnpc.com/pages/install-lnmp-on-osx] 安装Homebrew 最近工作环境切换到Mac,所以以OS X Yosemite(10.10.1)为例, ...
- Python—Socket
Socket模块 socket通常也称作"套接字",用于描述IP地址和端口,是特定网络协议如TCP/IP.UDP/IP套件对网络应用程序提供者提供的当前可移植标准的对象, 用来连接 ...
- :before\:after伪元素用法
:before和:after这两个伪元素在真正的页面元素之前和之后插入一个额外的的元素,等效于下面的代码: <p> <span>:before</span> HTM ...
- [Machine-Learning] 机器学习中的几个度量指标
Several classification metrics for ML/DM methods. 主要解释下机器学习(或数据挖掘)中的几个度量指标. 1. 关于 "TN/TP/FN/FP&q ...
- 无法嵌入互操作类型“ESRI.ArcGIS.Carto.RectangleElementClass”。请改用适用的接口。
右键点击应用的程序集 ESRI.ArcGIS.Controls,修改"嵌入互操作类型"的值即可
- Oracle子查询(嵌套查询)
概念: 所谓子查询,即一个select语句中嵌套了另外的一个或者多个select语句 需求:查找和Smith同部门的所有员工的id和last_name 目标: 员工id,last_name from: ...