JavaScript中的类(二)

一些基本概念

在对象上创建新属性时属性上的configurable,writeable,enumerable默认值为true,value默认undefined

用Obejct.defineProperty()创建新属性时,默认为false

_year前面的下划线表示只能通过对象方法访问的属性

在不能使用Object.defineProperty的对象方法中,可以使用__defineGetter__和__defineSetter__来实现

Object.getOwnPropertyDescriptor只能用于实例属性

Object.keys获取对象上所有的可枚举的实例属性

直接覆盖原型对象prototype的赋值方式会导致constructor属性不在指向构造函数,手动指向构造函数时,需要重新设定constructor的enumerable属性为false

实例中的指针仅指向原型,而不指向构造函数

不推荐在产品化的程序中修改原生对象的原型

节省内存的做法:构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性

实现方式

动态原型模式:在拥有相同原型对象的任意一处需要调用该原型对象上某方法的实例中,可以动态的判断该方法是否存在,若存在,则使用该方法,若不存在,则在原型对象上定义该方法,其他的实例也能实时的使用该方法。

寄生构造函数模式:

function SpecialArray(){
    var values=new Array();
    values.push.apply(values,arguments);
    values.toPipedString=function(){
        return this.join(',');
    }
    return values;
}

稳妥构造函数模式:类似于寄生构造函数模式,指不使用公共属性,其方法也不引用this对象

类的继承

function a(){
    this.aprop=true;
}

a.prototype.getAvalue=function(){
    return this.aprop;
}

function b(){
    this.bprop=false;
}

b.prototype=new a();

b.prototype.getBvalue=function(){
    return this.bprop;
}

 借用构造函数继承来解决继承过程中引用类型的值所带来的问题(即在原型对象上存在引用类型的值时,子类的修改会影响到父类),以上代码可以更新如下:

function a(){
    this.aprop=[1,2,3];
}

a.prototype.getAvalue=function(){
    return this.aprop;
}

function b(){
    a.call(this);
}

 b.prototype=new a();

b.prototype.getBvalue=function(){
    return this.bprop;
}

 以上方式调用了两次a构造函数,生成了两次a的实例,即aprop的实例在内存中存在两份,因此最终改进方式如下:

寄生组合式继承

function inherit(a,b){
    var prototype=Object(a.prototype);
    prototype.constructor=b;
    b.prototype=prototype;
}

function a(){
    this.aprop=[1,2,3];
}

a.prototype.getAvalue=function(){
    return this.aprop;
}

function b(){
    a.call(this);
}

 b.prototype=inherit(a,b);

b.prototype.getBvalue=function(){
    return this.bprop;
}
原文地址:https://www.cnblogs.com/goOtter/p/9388837.html