Object.create()和setPrototypeof和Child.prototype = Parent.prototype和Child.prototype = new Parent()的区别(

Posted fenglinwanyue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Object.create()和setPrototypeof和Child.prototype = Parent.prototype和Child.prototype = new Parent()的区别(相关的知识,希望对你有一定的参考价值。

 

Child.prototype = Parent.prototype和Child.prototype = new Parent()的区别

## 1、Child.prototype = new Parent()取不到Child原型上的属性,constructor指向Parent
//父类
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 + ‘生成氧气。‘)
    }

使用Object.create

 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更适和直接对一个无原生原型的对象快速进行委托。

 


以上是关于Object.create()和setPrototypeof和Child.prototype = Parent.prototype和Child.prototype = new Parent()的区别(的主要内容,如果未能解决你的问题,请参考以下文章

Object.create

Object.create 方法

ES6中Object.assign()和Object.create()

Object.create(null)和{}创建对象的区别

object.create(null) 和 {}创建对象的区别

Object.create()和new 创建对象的区别