【问题标题】:javascript Object.create()javascript Object.create()
【发布时间】:2016-05-06 10:48:10
【问题描述】:
function Shape() {}

Shape.prototype.move = function(x, y) {
  console.info('Shape moved.');
};

function Rectangle() {
  Shape.call(this); 
}

Rectangle.prototype = Object.create(Shape.prototype);

console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
rect.move(1, 1); // Outputs, 'Shape moved.'

我从 MDN 看到了这个例子。 我可以知道用 Rectangle.prototype = Shape.prototype; 替换 Rectangle.prototype = Object.create(Shape.prototype); 是否有重大变化? 两种情况下的结果是相同的。 有人告诉我原型属性本身就是一个对象,那么为什么我们要先使用 object.create() 创建另一个对象,然后将其分配给矩形的属性呢?为什么不直接将形状的原型分配给矩形?

【问题讨论】:

    标签: javascript object prototype


    【解决方案1】:

    让我们扩展您的示例以查看差异。

    function Shape() {}
    
    Shape.prototype.move = function(x, y) {
      console.info('Shape moved.');
    };
    
    function Rectangle() {
      Shape.call(this); 
    }
    
    Rectangle.prototype = Object.create(Shape.prototype);
    
    Rectangle.prototype.move = function(x, y) {
      console.info('Rectangle moved.');
    };
    
    var shape = new Shape();
    var rect = new Rectangle();
    console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
    console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
    shape.move(1, 1); // 'Shape moved.'
    rect.move(1, 1); // 'Rectangle moved.'
    

    现在让我们看看当你不使用Object.create()时会发生什么:

    function Shape() {}
    
    Shape.prototype.move = function(x, y) {
      console.info('Shape moved.');
    };
    
    function Rectangle() {
      Shape.call(this); 
    }
    
    Rectangle.prototype = Shape.prototype;
    
    Rectangle.prototype.move = function(x, y) {
      console.info('Rectangle moved.');
    };
    
    var shape = new Shape();
    var rect = new Rectangle();
    console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
    console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
    shape.move(1, 1); // 'Rectangle moved.'
    rect.move(1, 1); // 'Rectangle moved.'
    

    当您不使用Object.create() 基于Shape.prototype 对象创建新原型时,您只是分配对现有原型的引用,然后当您覆盖Rectangle 的一些原型方法时,您实际上也覆盖了Shape 的原型方法,因为它是同一个对象。

    【讨论】:

      【解决方案2】:

      如果你使用

      Rectangle.prototype = Shape.prototype;

      RectangleShape 原型都是同一个对象,您添加到 Rectangle 的每个方法/属性都将出现在 中形状也

      【讨论】:

        【解决方案3】:

        这种方法Rectangle.prototype = Object.create(Shape.prototype); 将确保Shape.prototype 在其(Shape.prototype)基本功能方面被Rectangle 继承。这可以防止Shape.prototypeRectangle.prototype 修改。
        考虑以下几点:

        ...
        Rectangle.prototype = Shape.prototype; // Shape.prototype is assigned as reference
        var rect = new Rectangle();
        
        Rectangle.prototype.add = "add method";
        console.log(JSON.stringify(Shape.prototype,0,4));
        ...
        // the output will be like(Shape.prototype was changed):
        {
            "add": "add method"
        } 
        

        如您所见,将Shape.prototype 直接分配给Rectangle.prototype 作为引用允许Rectangle.prototype 修改Shape.prototype
        Object.create(Shape.prototype) 将被分配为新的“独立”对象(所有Rectangle.prototype扩展不会影响Shape.prototype)

        【讨论】:

          猜你喜欢
          • 2016-05-24
          • 2014-06-24
          • 2013-01-04
          • 2016-07-10
          • 2012-10-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多