转载:javascript中定义兑现改的5种方式

本文转载自: http://www.phpfuns.com/scripts/javascript/five-method-define-javascript-object.shtml

 

 

JavaScript中定义对象的5种方式(JavaScript中没有类的概念,只有对象)

i)基于已有对象扩充其属性和方法

var object = new Object();
object.name = "zhangsan"; // 添加name属性
object.sayName = function(name){//添加sayName方法
    this.name = name;
    alert(this.name);
};
object.sayName("kyle");//调用sayName方法,name属性被修改为kyle,浏览器将打印kyle

最简单的一种方式,使用起来并不方便,适合于临时需要一个对象。

 

ii)工厂方式创建对象

不带参数的工厂方法:

//工厂方法
function createObject(){
    var object = new Object();        //创建一个对象
    object.name = "zhangsan";        //为该对象添加一个name属性
    object.password = "123";        //为该对象添加一个password属性
    object.get = function(){        //为该对象添加一个get方法
        alert(this.name+","+this.password);
    };
    return object;    //返回该对象
}
var object1 = createObject();        //调用createObject工厂方法创建对象object1
var object2 = createObject();        //调用createObject工厂方法创建对象object2
object1.get();                        //调用对象get方法
object2.get();                        //调用对象get方法

带参数的工厂方法:

function createObject(name, password) {
    var object = new Object();
    object.name = name;
    object.password = password;
    object.get = function() {
        alert(this.name + "," + this.password);
    };
    return object;
}
var object1 = createObject("zhangsan", "123");
var object2 = createObject("lisi", "456");
object1.get();
object2.get();

上面两种不带参数和带参数的工厂方法缺点:

每创建一个对象,内存中就创建一个get方法,比较浪费内存,且影响性能。而我们的期望是,创建两个不同的对象,它们的属性是不一样的,但方法是共用的。所以接下来我们需要改进createObject工厂方法。

改进的工厂方法:

// 把get()放在外面实现共用
function get() {
    alert(this.name + "," + this.password);
}
function createObject(name, password) { var object = new Object(); object.name = name; object.password = password; object.get = get; return object; } var object1 = createObject("zhangsan", "123"); var object2 = createObject("lisi", "456"); object1.get(); object2.get();

将get方法定义在createObject函数外面,这样每创建一个对象,get方法都是共用的。让一个函数对象被多个对象所共享,而不是每一个对象都拥有一个函数对象。

iii)构造函数方式创建对象

不带参数的构造函数

function Person(){
    //在执行第一行代码前,js引擎会为我们生成一个对象
    this.name = "zhangsan";
    this.password = "123";
    this.getInfo = function(){
        alert(this.name+","+this.password);
    };
    //此处有一个隐含的return语句,用于将之前生成的对象返回(也是跟工厂方式不一样的地方)
}
var p1 = new Person(); 
p1.getInfo();

带参数的构造函数

function Person(name, password) {
    this.name = name;
    this.password = password;
    this.getInfo = function() {
        alert(this.name + "," + this.password);
    };
}
var p1 = new Person("zhangsan", "123");
var p2 = new Person("lisi", "456");
p1.getInfo();
p2.getInfo();

iv)原型(prototype)方式创建对象

prototype是Object对象里面的一个属性,

function Person() {
}
Person.prototype.name = "zhangsan";
Person.prototype.password = "123";
Person.prototype.getInfo = function() {
    alert(this.name + "," + this.password);
};
var p1 = new Person();
var p2 = new Person();
p1.name = "kyle";// 对象生成之后再去改变属性 p1.getInfo(); p2.getInfo();

单纯地使用原型方式有两个问题:第一,你无法在构造函数中为属性赋初值,只能在对象生成之后再去改变属性值。

function Person() {
}
Person.prototype.name = new Array();
Person.prototype.password = "123";
Person.prototype.getInfo = function() {
    alert(this.name + "," + this.password);
};
var p1 = new Person();
var p2 = new Person();
p1.name.push("zhangsan");
p1.name.push("lisi");
p1.password = "456";
p1.getInfo();
p2.getInfo();

浏览器将会打印:zhangsan,lisi,456和zhangsan,lisi,123.

如果使用原型方式创建对象,那么生成的所有对象会共享原型中的属性,这样一个对象改变了该属性也会反应到其他对象当中。所以单纯地使用原型方式是不行的,还需要结合其他方式。接下来我们会继续介绍。

使用原型+构造函数方式来定义对象

function Person() {
    this.name = new Array();
    this.password = "123";
}
Person.prototype.getInfo = function() {
    alert(this.name + "," + this.password);
};
var p1 = new Person();
var p2 = new Person();
p1.name.push("zhangsan");
p2.name.push("lisi");
p1.getInfo();
p2.getInfo();

使用原型+构造函数方式来定义对象,对象之间的属性互不干扰,各个对象间共享同一个方法,这是一种比较好的方式。

v)动态原型方式

function Person() {
    this.name = "zhangsan";
    this.password = "123";
    if (typeof Person.flag == "undefined") {
        alert("invoked");
        Person.prototype.getInfo = function() {
            alert(this.name + "," + this.password);
        };
        Person.flag = true;
    }
}
var p1 = new Person();
var p2 = new Person();
p1.getInfo();
p2.getInfo();

在动态原型方式中,在构造函数中通过标志量让所有对象共享一个方法,而每个对象拥有自己的属性。上面代码在第一次创建对象时,首先通过一个判断语 句,看flag属性是否已经定义,若没有定义,则通过原型方式添加getInfo方法,然后将flag设置为true,那么当第二次创建对象时,if语句 判断为假,跳过执行。这样就达到了我们所期望的结果,创建的对象属性是互不干扰的,而对象的方法是共享的。

 

 

 

 

 

 

 

 

 

posted @ 2012-10-12 15:07  oaijuru  阅读(182)  评论(0编辑  收藏  举报