js对象创建
2016-04-22 14:31
302 查看
我们学过的面向对象语言有一个标志,它就是类,在ECMAScript中没有类的概念,但这并不影响,类就相当于无序属性的集合,在这里我们可以将ECMAScript中的对象想象成散列表。js中的面向对象程序设计中的创建对象部分有很多模式,比较抽象难理解,在这里根据课本和查阅的资料来总结一哈,希望也可以帮到你们
先来介绍一下几种模式:
1.工厂模式:它就比较普遍了,就是简单的写个js函数,并进行调用,特别之处就是用以特定函数来封装接口创建对象的细节
function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(o.name);
}
return o;
}
var person=createPerson("Lina",28,"Doctor");
缺点:可以无数次地调用这个函数,并且每次都会返回一个包含所定义的属性和方法的对象,解决了创建多个对象的问题,但是没有解决对象识别问题。
2.构造函数模式:
该模式用像Array和object这样的原生构造函数一样,进行自定义构造函数,从而自定义对象类型的属性和方法
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
}
}
var person1=new Person("Lina",28,"Doctor");
alert(person1 instanceof Person); //true
alert(person1 instanceof Object); //true
ps:在该模式中,函数名首字母大写,并用new操作符,创建一个新对象,将构造函数作用域赋给新对象,执行构造函数中的代码,为新对象添加属性和方法,返回该新对象。
在构造函数中不显式返回值,通它的实例过new来创建对象,当返回值为非对象时,忽略该返回值,当return的值为对象时,返回该对象。
缺点:构造函数模式可以将它的实例标识为一种特定的类型,当创建一个函数时,即创建了一个对象,当创建实例person1和person2时,会调用两次sayName函
4000
数,但是这两个函数却执行的是同一作用。
所以可以改变如下:
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=sayName;
}
function sayName(){
alert(this.name);
}
var person1=new Person("Lina",28,"Doctor");
将该函数改成全局函数,成为共享函数,但是全局变量只能被某个对象调用,造成对象和方法独立的问题。当调用完毕它的值可能会发生改变,而且如果需要定义多个全局变量函数,程序会显得更加冗余,并且可读性变低。
3.原型模式
function Person(){}
Person.prototype.name='Mary';
Person.prototype.age=28;
Person.prototype.sayName=function(){
alert(this.age);
};
var person1=new Person();
var person2=new Person();
person1.sayName();//28
person2.sayName();//28
ps:该模式通过创建一个函数,通过函数的prototype属性,直接为原型对象进行添加属性和方法,创建自定义构造函数后,原型对象默认只会取得constructer属性,而其他的属性则是从object继承来的。需要注意的是,在实例对象中,它也有一个内部指针[prototype],该指针指向构造函数的原型对象,这个链接存在于实例与原型对象,而不是实例与构造函数间。
缺点:构造函数无法传参,新创建的对象的属性和方法的值都是默认的,都是相同的,除此之外,如果给某个实例添加一个属性值时,他会同时改变每个实例的值。
4.组合使用构造函数模式和原型模式
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["Shelby","Court"];
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var person1=new Person("Nicholas",28,"singer");
var Person2=new Person("Greg",27,"dancer");
person1.friends.push("Van");
alert(person1.friends); //Shelby,Count,Van
alert(person2.friends); //Shelby,Count
ps:该模式通过构造函数定义实例属性,原型模式定义方法和共享的属性,集两种模式之长。
5.动态原型模式
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("Lida",28,"singer");
friend.sayName();
ps:第四种模式将构造函数和原型对象独立开来了,对于其他语言开发者来说有些奇怪,所以该模式将所有信息封装在构造函数中,在构造函数中初始化原型,并保持着构造函数和原型的优点。
相关文章推荐
- 介绍php设计模式中的工厂模式
- asp.net 简单工厂模式和工厂方法模式之论述
- 深入理解JavaScript系列(28):设计模式之工厂模式详解
- js简单工厂模式用法实例
- JavaScript设计模式经典之工厂模式
- javascript 模式设计之工厂模式详细说明
- 实例解析Java单例模式编程中对抽象工厂模式的运用
- javascript 原型模式实现OOP的再研究
- python中getattr函数使用方法 getattr实现工厂模式
- 实例讲解C++编程中对设计模式中的原型模式的使用
- 工厂模式在Zend Framework中应用介绍
- 浅析php工厂模式
- C++设计模式之原型模式
- C++设计模式之抽象工厂模式
- C++设计模式之简单工厂模式实例
- c#使用简单工厂模式实现生成html文件的封装类分享
- PHP高级对象构建 工厂模式的使用
- 基于php设计模式中工厂模式详细介绍
- javascript原型模式用法实例详解
- PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式