码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript - 创建对象的几种方式

时间:2015-03-18 23:16:05      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

1. 工厂模式

function createPerson(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert(this.name);
    };
    return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");

    这种方式有明显的缺点,就是没法知道对象的类型。

2. 构造函数模式

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
        alert(this.name);
    };
}

    这种方式的缺点在于每个sayName方法都要在每个实例上重新创建一遍

    每个方法都是一个Function实例,等同于

this.sayName = new Function("alert(this.name)");

    方法对于每个Person实例来说,应该是相同的,因此可以通过下面这种不好的方式(可能会增加很多全局函数,并且这些全局函数仅被某个对象调用)解决:

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;
}
function sayName(){
    alert(this.name);
}

3. 原型模式

    每个函数都有一个指向原型对象的属性,原型对象中的属性和方法是被共享的,那么,就可以不把属性和函数在构造方法中定义,而在原型对象中定义。

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};

    如果嫌每次都要敲prototype太繁琐,大可使用下面这种方式替代:

function Person(){
}
Person.prototype = {
    name : "Nicholas",
    age : 29,
    job: "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

    这种方式的一个弊端就是原型对象是新创建的对象,重写了原有的原型对象,因此其constructor属性不再指向Person构造函数,而是指向Object构造函数,这时只能通过instanceof判断其类型,不能通过constructor判断其类型了。但是,如果constructor属性很重要的话,也可通过下面方式设置:

function Person(){
}
Person.prototype = {
    constructor : Person,
    name : "Nicholas",
    ge : 29,
    job: "Software Engineer",
    sayName : function () {
        alert(this.name);
    }
};

    这样又出现了新问题:其constructor属性变为了可枚举的,如果JavaScript引擎支持ES5,可使用Object.defineProperty()重设构造函数。

    如果将属性和方法全在原型中定义,那就有可能会出大事。由于原型对象是被共享的,对于包含引用类型值的属性来说,一个实例的改变会影响所有的实例。

function Person(){};
Person.prototype = {
    friends: ["AAA","BBB"]
};
var p1 = new Person();
var p2 = new Person();
p1.friends.push("CCC");
alert(p2.friends);// AAA,BBB,CCC

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);
    }
}

    目前这种方式最常用。

5. 动态原型模式

    定义对象分为构造函数和原型两部分,看起来可能不太OO,那么可以在构造函数中初始化原型,让他表象更OO些。

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);
        };
    }
}

    这里就不能偷懒不写prototype了,XX.prototype = {blabla}的方式每次都会重写原型对象。

6. 稳妥构造函数

    某高人发明了稳妥对象这个概念,就是没有公共属性,也不能使用this拿到任何东西。在安全性要求比较高的时候使用,这些环境禁止使用this和new。

function Person(name, age, job){
    //创建要返回的对象
    var o = new Object();
    //可以在这里定义私有变量和函数
    //添加方法
    o.sayName = function(){
        alert(name);
    };
    //返回对象
    return o;
}

    这时就只能通过sayName()方法来访问name属性了。

JavaScript - 创建对象的几种方式

标签:

原文地址:http://www.cnblogs.com/sduzhangxin/p/4348852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!