JS重写原型

什么时候需要重写prototype

对于一个类,它天生自带一个属性:prototype。但是有时候,我们会重写类的原型。
比如,在继承的时候,我们想通过原型让子类B继承父类A的原型上的属性和方法(公有继承公有)。

function A() {
    this.x = 10;
}
A.prototype.say = function () {

};
function B() {
    this.y = 10;
}
B.prototype = A.prototype;
var b = new B;
console.log(b.say); //=>输出say函数体

通过B.prototype = A.prototype;让子类B的原型重新指向一个地址。

重写原型需要注意的点(恢复constructor和恢复原有方法)

  1. 对于内置类(如Object)的原型,浏览器为了保护里面的内置方法,是不允许重新创建一个堆内存覆盖原有的。
Object.prototype = {
    a:function () {

    }
};
console.log(Object.prototype);  //输出原来的Object.prototype
注:在IE浏览器中,浏览器禁止使用__proto__这个属性(本身存在,只不过被保护起来了,不允许使用)
  1. 我们手动创建一个新的内存给Fn.prototype,此时,这个手动创建的prototype是不会默认自带constructor属性的(使用instanceof运算符就无法找到实例对象所属的类了)。
  2. 重写原型,会把之前浏览器默认创建的prototype覆盖,所以之前在原型上的方法和属性都不存在了,需要恢复。
    恢复类默认原型上的属性和方法:
    function Fn() {
    
    }
    Fn.prototype.b = function () {
        console.log(1);
    }
    var pro = Fn.prototype;
    Fn.prototype = {
        constructor: Fn,    // 无法在recover中恢复,需要手动写
        b: function () {    // 重复方法b,在执行recover的时候会被原有的方法b覆盖
            console.log(2);
        },
        c: function () {
    
        },
        recover: function () {  //recover是在不知道原有类的原型上是否存在方法的时候,编写的一个还原原有公有属性和方法的函数
            for(var key in pro){
                this[key] = pro[key];
            }
        }
    }
    Fn.prototype.recover(); //执行后恢复
    var f = new Fn;
    f.b();  //=>1
    
    注意两点:
    1)for in循环能遍历对象中所有的属性和方法(私有+公有),但对于浏览器内置的一些属性(如constructor__proto__等),无法用for in遍历获取,这是浏览器对内置属性和方法的一个保护。
    2)在recover方法中,为了防止还原时原有的方法将自定义原型方法的覆盖,最好修改自定义方法名。优化recover方法
    recover: function () {	//优化后的recover
        for(var key in pro){
            if(key in this){
                this["my_"+key] = this[key];
                this[key] = null;
            }
            this[key] = pro[key];
        }
    }
    var f = new Fn;
    f.b();	//=>1
    f.my_b();  //=>2
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值