JavaScript面向对象的程序设计--创建对象

面向对象的程序设计--创建对象

1、工厂模式

涵义:抽象了具体创建对象的过程,用函数来封装以特定接口创建对象的细节。

优点:解决了创建多个相似对象的问题。

缺点:没有解决对象识别的问题。

function createPerson(name, age, job) {
    let o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    };
    return o;
}

let person1 = createPerson("Vince", 26, "FE"); 
let person2 = createPerson("Yisimo", 18, 'Poet'); 
console.log('person1', person1) //{name: "Vince", age: 26, job: "FE", sayName: ƒ}
console.log('person2', person2) //{name: "Yisimo", age: 18, job: "Poet", sayName: ƒ}

 

2、构造函数模式

涵义:创建自定义的构造函数,从而定义自定义对象的属性和方法。

优点:解决了对象识别的问题,可以将它的实例标识为一种特定的类型。

缺点:每个方法都要在每个实例上重新创建一遍,会导致不同的作用域链和标识符解析。

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

let person3 = new Person("Vince", 25, "FE");
let person4 = new Person("Yisimo", 20, "Poet");    
console.log('person3', person3) // Person {name: "Vince", age: 25, job: "FE", sayName: ƒ}
console.log('person4', person4) // Person {name: "Yisimo", age: 20, job: "Poet", sayName: ƒ}

 

3、原型模式

涵义:不在构造函数中定义实例的信息,而是将这些信息直接添加到原型对象中。

优点:可以让所有对象实例共享原型对象包含的属性和方法。

缺点:所有对象实例共享一个数组,实例没有属于自己的全部属性;省略了为构造函数传递初始化参数的环节,所有实例在默认情况下都取得相同的属性值。

function PersonProto() {}
    PersonProto.prototype = {
    constructor: PersonProto,
    name: 'Vince',
    age: '26',
    job: 'FE',
    sayName: function() {
        alert(this.name);
    }
};

let person5 = new PersonProto();
let person6 = new PersonProto();
person6.name = "Yisimo";
person6.age = 20;
console.log(person5.name, person5.age) // Vince 26
console.log(person6.name, person6.age) // Yisimo 20

 

4、组合使用构造函数模式和原型模式

涵义:混成模式,构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。目前使用最广泛、认同度最高的一种模式。

优点:每个实例都有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度地节省了内存;还支持向构造函数传参。

function PersonHybrid(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["John", "Mike"];
}

PersonHybrid.prototype = {
    constructor: PersonHybrid,
    sayName: function() {
        alert(this.name);
    }
}

let person7 = new PersonHybrid("Vince", 22, "FE");
let person8 = new PersonHybrid("Yisimo", 20, "Poet");
person7.friends.push("Van");
console.log(person7.friends); // ["John", "Mike", "Van"]
console.log(person8.friends); // ["John", "Mike"]
console.log(person7.friends === person8.friends); // false
console.log(person7.sayName === person8.sayName); // true

 

5、动态原型模式

涵义:把所有信息都封装在构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了同时使用构造函数和原型的特点。

function PersonDynamic(name, age, job) {
    // 属性
    this.name = name;
    this.age = age;
    this.job = job;
    // 方法
    if (typeof this.sayName != 'function') {
        PersonDynamic.prototype.sayName = function() {
            alert(this.name);
        }
    }
}

let person9 = new PersonDynamic("Vince", 23, "FE");
person9.sayName(); // Vince

 

6、寄生构造函数模式

涵义:基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

备注:除了使用new操作符,并把使用的包装函数叫做构造函数之外,该模式与工厂模式其实是一模一样的。

function PersonParasitic(name, age, job) {
    let o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}

let person10 = new PersonParasitic("Vince", 21, "FE");
person10.sayName(); // Vince

 

7、稳妥构造函数模式

涵义:遵循与寄生构造函数类似的模式,但有两点不同:一是新创建对象的实例方法不引用this;二是不使用new操作符调用构造函数。

备注:适合在安全环境中,或者在防止数据被其他应用程序改动时使用。

function PersonParasitic(name, age, job) {
    let o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(name);
    }
    return o;
}

let person11 = new PersonParasitic("Vince", 21, "FE");
person11.sayName(); // Vince 除了使用sayName()方法外,没有别的方式可以访问其数据成员。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值