JavaScript深入之创建对象的多种方式以及优缺点

https://juejin.im/post/6844903477542387719

  1. 工厂模式
    new Object然后往实例加属性方法,返回实例
    缺点:对象无法识别class,因为所有的实例都指向一个原型

  2. 构造函数模式
    new Class
    优点:实例可以识别为一个特定的类型
    缺点:每次创建实例时,每个方法都要被创建一次

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

var person1 = new Person('kevin');

2.1 构造函数模式优化
方法提取出来了
优点:解决了每个方法都要被重新创建的问题
缺点:这叫啥封装……

function Person(name) {
    this.name = name;
    this.getName = getName;
}

function getName() {
    console.log(this.name);
}

var person1 = new Person('kevin');
  1. 原型模式
    new Class,但是属性方法都在原型上。。。。
    优点:方法不会重新创建
    缺点:1. 所有的属性和方法都共享 2. 不能初始化参数
function Person(name) {

}

Person.prototype.name = 'keivn';
Person.prototype.getName = function () {
    console.log(this.name);
};

var person1 = new Person();

3.1 原型模式优化
优点:封装性好了一点
缺点:重写了原型,丢失了constructor属性

function Person(name) {

}

Person.prototype = {
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();

3.2 原型模式优化
优点:实例可以通过constructor属性找到所属构造函数
缺点:原型模式该有的缺点还是有

function Person(name) {

}

Person.prototype = {
    constructor: Person,
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();
  1. 组合模式
    构造函数模式与原型模式双剑合璧,推荐的Class写法
    优点:该共享的共享,该私有的私有,使用最广泛的方式
    缺点:有的人就是希望全部都写在一起,即更好的封装性
function Person(name) {
    this.name = name;
}

Person.prototype = { // 这里可以换成 3.原型模式 那种prototype写法
    constructor: Person,
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();

4.1 动态原型模式

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

var person1 = new Person();

注意:使用动态原型模式时,不能用对象字面量重写原型
原因如下:

function Person(name) {
    this.name = name;
    if (typeof this.getName != "function") {
        Person.prototype = {
            constructor: Person,
            getName: function () {
                console.log(this.name);
            }
        }
    }
}

var person1 = new Person('kevin');
var person2 = new Person('daisy');

// 报错 并没有该方法
person1.getName();

// 注释掉上面的代码,这句是可以执行的。
person2.getName();
image.png

image.png

5.1 寄生构造函数模式
寄生-构造函数-模式,也就是说寄生在构造函数的一种方法。
也就是说打着构造函数的幌子挂羊头卖狗肉,你看创建的实例使用 instanceof 都无法指向构造函数!
你会发现,其实所谓的寄生构造函数模式就是比工厂模式在创建对象的时候,多使用了一个new,实际上两者的结果是一样的。
在可以使用其他模式的情况下,不要使用这种模式。

function Person(name) {

    var o = new Object();
    o.name = name;
    o.getName = function () {
        console.log(this.name);
    };

    return o;

}

var person1 = new Person('kevin');
console.log(person1 instanceof Person) // false
console.log(person1 instanceof Object)  // true

5.2 稳妥构造函数模式
所谓稳妥对象,指的是没有公共属性,而且其方法也不引用 this 的对象。
与寄生构造函数模式有两点不同:

  • 新创建的实例方法不引用 this
  • 不使用 new 操作符调用构造函数

稳妥对象最适合在一些安全的环境中。
稳妥构造函数模式也跟工厂模式一样,无法识别对象所属类型。

function person(name){
    var o = new Object();
    o.sayName = function(){
        console.log(name);
    };
    return o;
}

var person1 = person('kevin');

person1.sayName(); // kevin

person1.name = "daisy";

person1.sayName(); // kevin

console.log(person1.name); // daisy

你可能感兴趣的:(JavaScript深入之创建对象的多种方式以及优缺点)