面向对象基础-原型重定向

334 阅读2分钟

面向对象基础-原型重定向

情景:有时候,我们需要向一个对象的原型对象上进行扩展,有两种方法

  1. fn.prototype.a=function(){}
    
  2. fn.prototype={
        a:function(){
            //......
        },
        b(){
            //......
        }
    }
    

    注意:在2中你会发现,使用了两种方法定义方法a,b这两种方式的区别:

    定义方式1:可以进行new

    定义方式2:不可以进行new

    观察两者的区别后的结论是,以前者,其有原型对象prototype,其原型对象上有constructor(构造函数属性),后者则没有原型对象,更没有构造函数方法。

第二种扩展原型对象的方式叫做重定向,原型重定向后,其原来的原型对象会被释放,prototype指针会指向新开辟的对象。

可能有人会问,fn原型重定向后没有了构造函数属性,为什么还可以被new?原因就是原型链,对象的原型方法上有constructor属性

原型重定向另外一个常用的方法就是使用Object.assign()方法

fn.prototype=Object.assign(obj1,obj2/*......*/)

Object.assign()方法是用于对象合并的,只不过是浅合并

例如:

 let obj1 = {
      a: {
        name: "rose",
        age: 18,
      },
      b: {
        name: "jack",
        age: 18,
      },
 };
 let obj2 = {
     a: {
        title: "原型重定向",
     },
 };
 let obj3 = Object.assign(obj1, obj2);
 console.log(obj3);
/*
 a: {
        title: "原型重定向",
  },
 b: {
        name: "jack",
        age: 18,
 }
*/
 console.log(obj1 === obj3);//true

由上面的例子可以看出来,它并没有实现对象内部a对象的合并,只合并了一层!

我们经常使用的原型重定向方式

  1. fn.prototype=Object.assign(fn.prototype,{/*扩展部分*/})
    //这种操作会保留原先原型上的方法和属性,并且不会销毁原来的原型对象
    
  2. fn.prototype=Object.assign({},fn.prototype,{/*扩展部分*/})
    //新开辟一个对象,作为fn的原型对象,但是,原来的原型对象由于没有了引用就会被js垃圾回收机制回收