美文网首页
javascript深入理解系列(五)——new和Object.

javascript深入理解系列(五)——new和Object.

作者: 悦者生存 | 来源:发表于2018-12-27 15:05 被阅读12次

    生成实例对象的常用方法是,使用new命令让构造函数返回一个实例。但是很多时候,只能拿到一个实例对象,它可能根本不是由构造函数生成的,那么能不能从一个实例对象,生成另一个实例对象呢?

    JavaScript 提供了Object.create方法,用来满足这种需求。该方法接受一个对象作为参数,然后以它为原型,返回一个实例对象。该实例完全继承原型对象的属性。

    // 原型对象
    
    var A = {
      print: function () {
        console.log('hello');
      }
    };
    
    // 实例对象
    var B = Object.create(A);
    
    Object.getPrototypeOf(B) === A // true
    B.print() // hello
    B.print === A.print // true
    上面代码中,Object.create方法以A对象为原型,生成了B对象。B继承了A的所有属性和方法。
    
    实际上,Object.create方法可以用下面的代码代替。
    
    if (typeof Object.create !== 'function') {
      Object.create = function (obj) {
        function F() {}
        F.prototype = obj;
        return new F();
      };
    }
    上面代码表明,Object.create方法的实质是新建一个空的构造函数F,然后让F.prototype属性指向参数对象obj,最后返回一个F的实例,从而实现让该实例继承obj的属性。
    
    下面三种方式生成的新对象是等价的。
    
    var obj1 = Object.create({});
    var obj2 = Object.create(Object.prototype);
    var obj3 = new Object();
    如果想要生成一个不继承任何属性(比如没有toString和valueOf方法)的对象,可以将Object.create的参数设为null。
    
    var obj = Object.create(null);
    
    obj.valueOf()
    // TypeError: Object [object Object] has no method 'valueOf'
    上面代码中,对象obj的原型是null,它就不具备一些定义在Object.prototype对象上面的属性,比如valueOf方法。
    
    使用Object.create方法的时候,必须提供对象原型,即参数不能为空,或者不是对象,否则会报错。
    
    Object.create()
    // TypeError: Object prototype may only be an Object or null
    Object.create(123)
    // TypeError: Object prototype may only be an Object or null
    Object.create方法生成的新对象,动态继承了原型。在原型上添加或修改任何方法,会立刻反映在新对象之上。
    
    var obj1 = { p: 1 };
    var obj2 = Object.create(obj1);
    
    obj1.p = 2;
    obj2.p // 2
    上面代码中,修改对象原型obj1会影响到实例对象obj2。
    
    除了对象的原型,Object.create方法还可以接受第二个参数。该参数是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该对象自身的属性。
    
    var obj = Object.create({}, {
      p1: {
        value: 123,
        enumerable: true,
        configurable: true,
        writable: true,
      },
      p2: {
        value: 'abc',
        enumerable: true,
        configurable: true,
        writable: true,
      }
    });
    
    // 等同于
    var obj = Object.create({});
    obj.p1 = 123;
    obj.p2 = 'abc';
    Object.create方法生成的对象,继承了它的原型对象的构造函数。
    
    function A() {}
    var a = new A();
    var b = Object.create(a);
    
    b.constructor === A // true
    b instanceof A // true
    上面代码中,b对象的原型是a对象,因此继承了a对象的构造函数A。
    

    相关文章

      网友评论

          本文标题:javascript深入理解系列(五)——new和Object.

          本文链接:https://www.haomeiwen.com/subject/pzjvwftx.html