007-js创建对象的几种方式

1.字面量方式创建

var person = {
    name: 'James',
    age: 20,
    say: function() {
        console.log(this.name);
    }
}

此种方式缺点:创建很多对象的时候,会产生很多重复代码

2.工厂模式

为了解决重复代码的问题,使用工厂模式创建对象

function createPerson(name, age) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.say = function() {
        console.log(this.name);
    }
    return o;
}

var person1 = createPerson('James', 20);
var person2 = createPerson('Jack', 23);

person1.say();
person2.say();

工厂模式虽然解决了代码重复的问题,但是又有新的问题了,就是对象识别的问题,因为这些对象都来自我们new出来的Object。下面的一种模式就解决了这个问题

3.构造函数模式

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.say = function() {
        console.log(this.name)
    }
} 

var person1 = new Person('James', 20);
var person2 = new Person('Jack', 23);

person1.say();
person2.say();

之前我们说了,工厂模式无法解决对象识别的问题,那么构造函数模式是否解决了呢,我们验证一下

console.log(person1 instanceof Person);  // true
console.log(person2 instanceof Person);  // true

由此可见,对象识别是成功了的!

我们观察发现这种模式跟第二种工厂模式很类似,但是也有些区别:

  • 在Person里并没有创建对象
  • 使用new

那么到底发生了什么呢?

4.原型模式

什么是原型,请看008-JS原型和原型链
使用原型对象的好处是可以让所有对象实例共享它包含的属性和方法。我们不需要在构造函数中添加属性和方法,这些东西一股脑都放到原型中。

function Person() {}

Person.prototype = {
    name: 'James',
    age: 20,
    say: function() {
        console.log(this.name)
    }
}

var person = new Person();
person.say();

原型模式也是有缺点的:

  • 原型的属性的值被定义为固定值,那么所有实例的属性的值都会成为固定值
  • 原型的属性为引用类型的时候,容易导致篡改属性
function Person() {}

Person.prototype = {
    friends: ['Jack', 'Tom']
}

var person1 = new Person();
var person2 = new Person();
person1.friends.push('Teddy');
console.log(person2.friends);  // [ 'Jack', 'Tom', 'Teddy' ]

我们发现,实例person1的数组friends改变之后,实例person2的friends也被改变了
为了解决这个问题,有了组合使用构造函数模式和原型模式

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

所谓组合使用构造函数模式和原型模式,就是拿出两种模式的优点,创造出一种新的模式。

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

Person.prototype.say = function() {
    console.log(this.name);
}

var person1 = new Person('James', 20);
var person2 = new Person('Jack', 23);

person1.say();
person2.say();

在此种模式中,我们把属性放在构造函数中,把方法放在原型中。这样既能保证实例可以传入属性,又能确保方法可以共享,一举两得。这也是目前使用最多的一种模式。

6.动态原型模式

function Person(name, age) {
    this.name = name;
    this.age = age;

    if(typeof this.say != 'function') {
        Person.prototype.say = function() {
            console.log(this.name);
        }
    }
}

var person = new Person('James', 20);
person.say()

参考:《JavaScript高级程序设计》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值