美文网首页
原型属性的继承

原型属性的继承

作者: keknei | 来源:发表于2019-06-04 17:00 被阅读0次

    我们先定义一个函数对象,并在这个函数的原型上添加属性

    let o1={
      a:1
    };
    function Fn(){
      this.x=10;
    }
    Object.assign(Fn.prototype,o1);
    
    let fn1=new Fn();
    

    我们再添加一个可枚举属性,并添加get描述符

    Object.defineProperty(fn1,"getA",{
      enumerable: true, // 设为可枚举,不然 Object.assign 方法会过滤该属性
      get(){
          return "Could it return " + this.a
      }
    });
    
    console.log(fn1.x);//10
    console.log(fn1.a);//1
    

    我们先用Object.assign()来拷贝这个函数对象,看怎么样

    let fn2=Object.assign({},fn1);
    console.log(fn2.x);//10
    console.log(fn2.a);//undefined
    

    我们会发现原型上的a属性没有拷贝过来,因为Object.assing是不能拷贝到继承或原型上的方法或者属性的,只能拷贝对象自身的属性

    解决拷贝原型上的方法或者属性的两种方法

    1. 先获取原型上的属性,然后再创建一个有这个原型上的属性的对象,最后再将拷贝对象的自身属性拷贝到这个创建对象上
    let proto=Object.getPrototypeOf(fn1);
    let obj=Object.create(proto);
    Object.assign(obj,fn1);
    console.log(obj.x);//10
    console.log(obj.a);//1
    

    Object.assign不能正确拷贝get描述符,看obj的getA属性,只能获取值

    console.log(obj);
    
    console.log(obj)

    所以我们推荐用第二种方法

    1. 直接创建一个对象,然后这个对象的原型就是获取拷贝对象的原型,自身属性就是拷贝对象上的自身属性
    let obj2=Object.create(Object.getPrototypeOf(fn1),Object.getOwnPropertyDescriptors(fn1));
    console.log(obj2.x);//10
    console.log(obj2.a);//1
    

    我们再看这个拷贝完的obj2,是否完全拷贝了函数对象

    console.log(obj2);
    
    console.log(obj2)

    这种方法就可以正确的拷贝到了get描述符了


    • 如果只是拷贝 自身可枚举属性,就可以只用 Object.assign 方法;
    • 如果是要拷贝原型上的属性,就需要 Object.assign , Object.create, Object.getPrototypeOf 方法结合使用
    • 如果是拷贝get /set 属性,就需要结合Ojbect.getOwnPropertyDescriptors 方法

    相关文章

      网友评论

          本文标题:原型属性的继承

          本文链接:https://www.haomeiwen.com/subject/unhrxctx.html