Object.create()和setPrototypeof和Child.prototype = Parent.prototype和Child.prototype = new Parent()的区别
## 1、Child.prototype = new Parent()取不到Child原型上的属性,constructor指向Parent 修正:Child.prototype = new Parent() 会导致Child多个实例指向同一个引用,因为new Parent返回的是一个引用类型,此时修改Child的某个实例的属性,
其它实例的属性也会被修改。
//父类 function Parent(){ this.name = "P_Name"; } Parent.prototype.func=function(){ console.log("Parent Func"); } //子类 function Child(){ } Child.prototype=new Parent(); Child.prototype.func = function(){ console.log("Child Func"); } var child = new Child; var parent = new Parent; child.func();//Child Func console.log(child.name);//P_Name console.log(Child.prototype.constructor) // Parent parent.func();//Parent Func ## 2、Child.prototype = Parent.prototype取不到Parent的构造函数属性,constructor指向Parent,而且对子类的原型方法重写会使父类的原型方法被重写 function Child2(){ } # 以下赋值将覆盖Parent.prototype.func方法 Child2.prototype=Parent.prototype; Child2.prototype.func = function(){ console.log("Child2 Func"); } var child2 = new Child2; child2.func();//Child2 Func console.log(child2.name);//undefined console.log(Child2.prototype.constructor) // Parent parent.func();//Child2 Func
setPrototypeOf 与 Object.create区别
可以用prototype访问的只有function类型,其他类型只能用getPrototypeOf或者proto,其他类型也都是通过function生成的(String,Number……涉及到隐式创建对象)
对象的原型只是一个引用,指向另外一个对象。对象原型之间的嵌套组成了原型链,原型链的作用是维护访问对象属性的查询,确定访问权限。
若存在A和B俩个函数,让A的原型指向B
1.setPrortotypeOf
Object.setPrototypeOf(A.prototype,B.prototype)
2.Create
A.prototype = Object.create(B.prototype)
俩者都可以达到设置对象原型的功能,但是具体表现上有一些区别。
代码如下
function Animal (name,sound) { this.name = name this.sound = sound } Animal.prototype.shout = function () { console.log(this.name + this.sound) } let dog = new Animal('pipi','wang!wang!') // 定义Plants function Plants (name) { this.name = name this.sound = null } // 函数接收参数用于区分 Plants.prototype.shout = function (xssss) { console.log(this.name + this.sound +'plants tag') } Plants.prototype.genO2 = function () { console.log(this.name + '生成氧气。') }
Animal.prototype = Object.create(Plants.prototype) console.log(Animal.prototype) /* Plants {} __proto__: shout: ƒ (xssss) genO2: ƒ () constructor: ƒ Plants() __proto__: Object */ let cat = new Animal('mimi','miao~miao~') dog.shout() // pipi wang!wang! cat.shout() // mimi miao~miao~ plants tag cat.genO2() // mimi 生成氧气。
使用setPrototypeOf
Object.setPrototypeOf(Animal.prototype,Plants.prototype) console.log(Animal.prototype) /* Plants {shout: ƒ, constructor: ƒ} shout: ƒ (xssss) constructor: ƒ Animal(name,sound) __proto__: shout: ƒ () genO2: ƒ () constructor: ƒ Plants() __proto__: Object */ dog.shout() // pipi wang!wang! cat.shout() // mimi miao~miao~ cat.genO2() // mimi 生成氧气。
总结
使用Object.create,Animal.prototype将会指向一个空对象,空对象的原型属性指向Plants的prototytpe。所以我们不能再访问Animal的原有prototypoe中的属性。Object.create的使用方式也凸显了直接重新赋值。
使用Object.setPrototypeOf则会将Animal.prototype将会指向Animal原有的prototype,然后这个prototype的prototype再指向Plants的prototytpe。所以我们优先访问的Animal,然后再是plants。
在进行俩个原型之间的委托时使用setPrototype更好,Object.create更适和直接对一个无原生原型的对象快速进行委托。