fayeah / blogs

方法论、问题驱动、总结
6 stars 0 forks source link

构造函数模式 #28

Open fayeah opened 4 years ago

fayeah commented 4 years ago

构造函数模式使得可以创建多个新的实例,并且新对象的成员声明都是构造函数里定义的。在构造函数内部,this引用的是新创建的对象。

可以通过new创建实例

对这个实例对象标记为构造函数的类型

function Car(model, year, miles) {
    this.model = model;
    this.year = year;
    this.miles = miles;
    this.output= function () {
        return this.model + "走了" + this.miles + "公里";
    };
}
var tom = new Car("大叔", 2009, 20000);

prototype优化:

上面这种方式,每次使用构造函数创建一个新实例的时候,构造函数所有的属性和方法都会被重新拷贝,而原型方法,是一个引用方法:

function Car(model, year, miles) {
    this.model = model;
    this.year = year;
    this.miles = miles;
}

Car.prototype.output= function () {
    return this.model + "走了" + this.miles + "公里";
};

原型方法引用最初的方法,不会进行拷贝,进而能节约浏览器的内存。

不使用new关键字:

//方法1:作为函数调用
Car("大叔", 2009, 20000);  //添加到window对象上
console.log(window.output());

//方法2:在另外一个对象的作用域内调用
var o = new Object();
Car.call(o, "Dudu", 2010, 5000);
console.log(o.output()); 

对于方法一,如果没有使用new关键字,则构造函数的this指向的是全局对象window

//作为函数调用
var tom = Car("大叔", 2009, 20000);
console.log(typeof tom); // "undefined"
console.log(window.output()); // "大叔走了20000公里"

为了不使用new关键字,可以使用以下办法来解决this指向的问题:

function Car(model, year, miles) {
    if (!(this instanceof Car)) {
        return new Car(model, year, miles);
    }
    this.model = model;
    this.year = year;
    this.miles = miles;
    this.output = function () {
        return this.model + "走了" + this.miles + "公里";
    }
}

var tom = new Car("大叔", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000);

console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"

参考:https://www.cnblogs.com/TomXu/archive/2012/02/21/2352994.html