Object.create

var obj = {
    a:1,
    arr:[2,3,4]
}
var obj1 = Object.create(obj)
obj1.a = 2
obj1.arr.push(5)
console.log(obj1.a) // 2
var obj2 = Object.create(obj)
console.log(obj2.a)  // 1

根据 demo,可以推测出 Object.create 创建了一个新对象,并且创建的对象继承了obj这个对象的属性.而且改变对象的属性并不会影响原来对象的值.

Object.create(obj)创建了一个空对象,并且这个空对象的构造函数的原型指向了obj

简单的实现Object.create

function _create (obj){
    function F (){}
    F.prototype = obj
    return new F()
}

继续往下走:

obj1.arr.push(5)
console.log(obj1.arr)  // [2,3,4,5]
console.log(obj2.arr)  // [2,3,4,5]

为什么会出现这样的情况呢???
新创建的对象会共享原始对象中的引用的值,相当于进行了一次浅拷贝.

相对完善的写法:

if(typeof Object.create !== 'function'){
    Object.create = function (proto,propertiesObject){
        if(typeof proto !== 'object' && typeof proto !== 'function'){
            throw new TypeError(`Object prototype may only be an Object or null:${proto}`)
        }
        //这里不验证propertiesObject这个参数
        if(typeof propertiesObject !== 'undefined'){
            throw TypeError('这里不验证propertiesObject这个参数')
        }
        function F (){}
        F.prototype = proto
        return new F()
    }
}

new

new干了什么?

  • 创建了一个空对象
  • 将对象的原型赋值为构造函数的原型
  • 改变 this 的指向
  • 返回这个对象
function _new (){
    var obj = Object.create()
    Constructor = [].shift().call(arguments)
    obj.__proto__ = Constructor.prototype
    var ret = Constructor.apply(obj,arguments)
    return typeof ret === 'object' ? obj:ret
}

参考文章

https://juejin.im/post/5bf37a...
https://developer.mozilla.org...
https://github.com/mqyqingfen...


好好学习
7 声望2 粉丝

文章是自己在学习或踩到坑的过程中查找资料的总结,以便后期自己复习使用