JS中的创建对象

工厂模式

function createPerson(name, age) {
    let obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sayName = function () {
        console.log(obj.name);
    }
    return obj;
}

var person = createPerson("zhangsan", 1);

无法实现实例之间共享一些方法和属性;无法识别对象类型(因为返回的是一个Object,而不是一个 Person类)

构造函数模式

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function () {
        console.log(this.name);
    }
}
var person = new Person("zhangsan", 1);

可以解决如何识别对象类型的问题;
新建一个实例(new)的过程:

  1. 创建一个新对象
  2. 将构造函数的作用域赋值给新对象(this 指向这个新对象)
  3. 执行构造函数中的代码
  4. 返回新对象

对于函数复用的问题,可以采用将函数定义在构造函数外部,构造函数中只需指向外部这个函数

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

但定义在构造函数外面,如果对象需要定义很多方法,那么就要在构造函数外面定义多个全局函数,丝毫没有封装性可言。于是就提出了原型模式

原型模式

每个函数都有一个prototype属性,这个是一个指针类型,指向一个对象。这个对象的用处,可以让有这个函数创建的实例共享其属性和方法。

function Person() {

}
Person.prototype.name = 'zhangsan';
Person.prototype.age = 1;
Person.prototype.sayName = function () {
    console.log(this.name);
};
Person.prototype.firends = ['李四']
var a = new Person();
var b = new Person();
a.sayName(); // zhangsan
b.sayName(); //zhangsan
a.firends.push('王五');
console.log(b.firends); // ['李四', '王五']

原型模式虽然可以实现不同实例之间的共享属性和共享方法,但有些属性和方法并不想设置为共享。对于这个问题,可以采用构造函数+原型混合的模式

构造函数+原型模式

在构造函数中定义不需要共享的属性和方法,在原型模式中定义共享的部分

function Person(name, age){
    this.name = name;
    this.age = age;
    this.firends = [];
}
Person.prototype.sayName = function(){
    console.log(this.name);
}
var a =new Person('zhangsan',1);
var b = new Person('lisi',2);
a.firends.push('王五');
console.log(a.firends); // ['王五']
console.log(b.firends); // []

但构造函数和原型分开定义,对于其他有OO语言经验的开发者可能会造成困惑,为此,提出了一种动态原型模式

动态原型模式

它将所有的内容封装到构造函数中,如

function Person(name, age){
    this.name = name;
    this.age = age;
    // 在构造函数中增加判断,只有第一次执行时会触发。
    if(typeof this.sayNmae !='function'){
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    }
}

在以上几种模式都不适用的情况下,可以使用寄生构造函数模式

寄生构造函数模式

function Person(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this.name);
    }
    return o
}
var a = new Person('zhangsan', 1);

这中模式的思想时创建一个函数,该函数的作用仅仅时封装创建对象的代码,然后再返回新创建的对象。除了使用new操作符之外和,工厂模式其实一模一样。构造函数在不设返回值的情况下,返回新对象的实例。而通过在构造函数的末尾添加一个return,可以重写调用构造函数时返回的值。

稳妥构造函数模式

道格拉斯发明了一种稳妥对象,所谓的稳妥对象,指没有公共属性,而且方法中也不引用this的对象。稳妥对象最适合在一些安全环境(一些禁用this和new的环境)中使用
稳妥构造函数遵循与寄生构造函数相似的模式,但又两点不同:一是新创建对象的实例方法不引用this,二是不使用new操作符调用构造函数。可以将上面的Person重写如下

function Person(name,age){
    var o = new Object();
    // 可以定义私有变量和函数

    //添加方法
    o.sayName = function(){
            console.log(name);  // 这里是使用闭包
        }
    return o;
};

参考

红宝书

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值