创建js对象的几种方法

1.对象字面量的方式

缺点:使用同一个接口创建很多对象会产生大量重复代码,创建有相同属性的对象时,会产生重复代码

var person = {
    name:"nicl",
    age:14,
    sayName:function () {
        alert(this.name);
    }
};

2.工厂模式:

优点:解决了创建多个相似对象的问题,
缺点:没有解决对象识别的问题

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;
}
createPerson("zhangsan",14,"farmer");
createPerson("li",24,"toilet");

3.构造函数模式(大驼峰式命名规则)

function Person(name,age,job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
        alert(this.name);
    }
}
var person1 = new Person("ni",21,"coder");
var person2 = new Person("li",15,"student");

与工厂模式不同的是:
1.没有显示的创建对象;2.直接将属性和方法赋给了this对象;3.没有return语句
要创建一个Person实例必须使用new操作符,以这种方式调用构造函数会经历4个步骤:

  • 1:创建一个新的对象;
  • 2:将构造函数的作用域赋给新对象(this就指向了这个新的对象)
  • 3:执行构造函数中的代码(为新对象添加属性)
  • 4:返回新对象

缺点:每个方法都要在每个实例上重新创建一遍,在上面那个例子当中person1和person2都有一个sayName方法,但是这两个方法不是同一个Function的实例。这样可能比较好理解:

function Person1(name,age,job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function('alert(this.name)'); //不是同一个Function的实例,与之前的例子是等价的
}
var person3 = new Person1("nj",43,"teacher");
var person4 = new Person1("fdf",54,"child");
alert(person3.sayName === person4.sayName);   //false

4:原型模式

在js中,每个函数都有一个prototype属性,它是一个指针,指向一个对象,叫做原型对象,原型对象包含了可以由特定类型的所有实例对象共享的属性和方法。 此外,这个对象有一个与生自来的属性constructor,指向创建对象的构造方法。使用原型模式可以让所有的实例共享原型对象中的属性和方法,
也就是说,不必再构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

function Person2() {}
Person2.prototype.name = "nico";
Person2.prototype.age = 32;
Person2.prototype.job = "coder";
Person2.prototype.friends = ["she","he"];
Person2.prototype.sayName = function () {
    alert(this.name);
};
var person5 = new Person2();
person5.sayName();

var person6 = new Person2();
person6.sayName();
alert(person5.sayName === person6.sayName); //true

//可以通过对象实例来访问原型上的属性和方法,但是不能通过对象实例重写原型的值,如果我们在实例中添加了一个属性,该属性与原型上的属性同名
//那么该属性会屏蔽掉原型中的那个属性,代码如下:
person6.name = "mini";
alert(person6.name);  //mini

缺点:
首先,它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便, 但还不是原型的最大问题。原型模式的最大问题是由共享的本性所导致的。原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说的过去,通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然后,对于包含引用类型的属性来说,问题就比较突出了。

person5.friends.push('it');
alert(person5.friends); //she,he,it
alert(person6.friends); //she,he,it
alert(person6.friends === person5.friends); //true

向person5的friends字符串数组里面添加一项,由于friends是存在于原型中的,当更改person5时,person6的属性值也会跟着变化

5.构造函数与原型模式组合使用

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

function Person3(name,age,job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["lili","liming","joh"]
}
Person3.prototype.sayName = function () {
    alert(this.name);
};
var person7 = new Person3('zhang',23,'teacher');
var person8 = new Person3('li',2,'child');

person7.friends.push('fei');
alert(person7.friends); //lili,liming,joh,li
alert(person8.friends); //lili,liming,joh
alert(person7.friends === person8.friends); //false

参考书籍《JavaScript高级程序设计》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值