原型式继承-Object.create()的由来

我们可以从最初的混合继承模式,慢慢说起Object.create()的前因后果。

一般来说,使用构造函数结合原型的混合模式,可以为特定的实例共享属性和方法。

比较常见的是下面的形式,也是最基本的使用:

function Person(name){
    this.name = name;
};

Person.prototype.sayName = function(){
    alert(this.name);
}

Person.prototype.XXX = XXXXX;

......

var p1 = new Person('mike');
var p2 = XXXXX;
......

如果只是想达到实例共享属性,不想噼里啪啦的创建构造函数,懒得定义一大堆原型属性,,完全可以用更简洁的方法去实现。

比如,这么做:

定义于一个create函数,来对传入的obj对象加工,使obj对象作为构造函数Person的原型,最后返回一个临时的新实例。

function create(obj){
    function Person(){};
    Person.prototype = obj;
    return new Person();
}

var people = {
    name:'mike'
}

var p1 = create(people);

console.log(p1.name);       //mike

故事还在继续。。。

上面方法证明是可行的,不过有一个坑,那就是原型的引用类型属性会共享相应的值,举个栗子:

function create(obj){
    function Person(){};
    Person.prototype = obj;
    return new Person();
}

var people = {
    name:'mike',
    arr:[1,2,3,4,5]
}

var p1 = create(people);
var p2 = create(people);

p1.name = 'jake';
p1.arr.push('hahaha');

console.log(p1.name);       //jake
console.log(p2.name);       //mike

console.log(p1.arr);        //[1, 2, 3, 4, 5, "hahaha"]
console.log(p2.arr);        //[1, 2, 3, 4, 5, "hahaha"]

由于原型中的arr属性是引用类型,所以它是被实例所共享,上面可以看到原型中,基本类型属性和引用类型属性的差异。

后来、、、、

ES5看不下去了,所以新增了一个Object.create()方法,用于规范原型式继承。

Object.create()接收2个参数,一个(必选)是作为新对象原型的对象,另外一个(可选)为新对象定义额外属性的对象。

在只传入一个参数的情况下Object.create()与上面的create()用法相同:

var person = {
name:'mike',
    arr:[1,2,3,4,5]
}

var p1 = Object.create(person);
var p2 = Object.create(person);

p1.name = 'jake';
p1.arr.push('hahaha');

console.log(p1.name)        //jake
console.log(p2.name)        //mike

console.log(p1.arr)         //[1, 2, 3, 4, 5, "hahaha"]
console.log(p2.arr)         //[1, 2, 3, 4, 5, "hahaha"]

注意了,还是那个坑,包含引用类型的属性始终会共享相应的值。

Object.create()接收的第二个参数,是为新对象定义额外的属性,指定的任何属性都会覆盖原型上的同名属性。

var person = {
    name:'mike',
    arr:[1,2,3,4,5]
}

var p1 = Object.create(person,{
    name:{
        value:'jake'
    },
    arr:{
        value:[7,8,9]
    }
});
var p2 = Object.create(person);

p1.arr.push('hahaha');

console.log(p1.name)        //jake
console.log(p2.name)        //mike

console.log(p1.arr)         //[7, 8, 9, "hahaha"]
console.log(p2.arr)         //[1, 2, 3, 4, 5]

猜你喜欢

转载自blog.csdn.net/qq_35087256/article/details/80344705