当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 创建对象的几种模式

创建对象的几种模式

2018年11月02日  | 移动技术网IT编程  | 我要评论

孤独三国,2012f1欧洲站,美国总统来了

一般创建对象是用以下两种方式

new object创建对象:

var person = new object();
person.name = "张三";
person.age = "18";
person.job = "123";

或者,对象字面量的方式:

var person = {
    name:"lisi",
    age:"18",
    job:"123"
}

这两种方式的缺点是:同一个接口创建很多对象,会产生大量的重复代码,如var person1={},var person2={},为了解决这个问题,人们开始使用工厂模式的一种变体来创建对象。

一、工厂模式

由于在ecmascript中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下图:

function creatperson(name,age,job){
    var a = new object();
    a.name = name;
    a.age = age;
    a.job = job;
    return a;
}
var person2 = creatperson("lisi","17","456");

使用工厂模式创建对象,无论创建多少个对象,都只需要调用creatperson()函数,并传入相关参数即可。但是工厂模式也留下了一个问题,就是无法区分创建对象类型是什么,在ecmascript 中的构造函数可用来创建特定类型的对象 。

二、构造函数模式

function person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayname = function(){
        alert(this.name);
    }
}
var person1 = new person("lisi","18","123");

创建自定义的构造函数,从而定义自定义对象类型的属性和方法 。构造函数也是函数,它与普通函数唯一的区别就是调用方式不同。任何函数,只要用new操作符来调用,那它就可以作为构造函数。
缺点:函数即对象,sayname 是匿名函数对象;每调用实例化一次构造函数就会创建一个匿名函数对象,不同实例上的同名函数是不相等的,占用内存。

三、原型模式

理解原型:只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个 prototype属性,这个属性指向函数的原型对象。
在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向 prototype 属性所在函数的指针。

function person(){

}
person.prototype = {
    constructor:person,
    name:"张三",
    age:"18",
    job:"123",
    friends: ['小明', '小刚'],
    sayname:function(){
        alert(this.name);
    }
}
var person1 = new person();

这里将 person.prototype 设置为以对象字面量的形式创建的新对象,由于每创建一个新对象,就会同时创建它的 prototype原型对象,
这个对象也会自动获得 constructor 属性,这个constructor指向这个新创建的object对象,而不是person对象,为了使其指向person,
需添加 constructor:person

原型模式的缺点:

var p1 = new person();
var p2 = new person();
p2.name = '李四';
p1.friends.push('小红');// 指向同一个friends数组,修改的是原型中的friends
console.log(p1.friends);//["小明", "小刚", "小红"]
console.log(p2.friends);//["小明", "小刚", "小红"]
console.log(p1.friends == p2.friends);//true

缺点1:省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值

缺点2:对于原生构造函数(object、array等)的缺点:

p1的friends和p2的friends相同,因为p1修改了原型对象的friends,但我们需要的是它们不应该相同,
解决办法:将需要共享的属性或方法在原型中定义,将不需要共享的如:friends,在构造函数中定义

四、组合使用构造函数和原型模式

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。

function person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends: = ['小明', '小刚'],
}
person.prototype = {
    constructor:person,
    sayname:function(){
        alert(this.name);
    }
}

 

 

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网