【问题标题】:Difference between inheriting using .call() and prototype使用 .call() 和原型继承之间的区别
【发布时间】:2020-10-03 15:24:28
【问题描述】:

我最近在学习 javaScript,偶然发现了这个

  function Polygon() {
  this.dimensions = "2d";
  this.print = function () {
    console.log(" 2d dimensions are easy to work with!");
  }
}
function Quad() {
  Polygon.call(this);
  this.sides = 4;
}
var quad = new Quad();
quad.print();

function Polygon1() {}
Polygon1.prototype.dimensions = "2d";
Polygon1.prototype.print = console.log("2d dimensions are not difficult to work with!");

function Quad1() {
  this.sides = 4;
}
Quad1.prototype = Object.create(Polygon1.prototype);
Quad1.prototype.constructor = Quad1;

var quad1 = new Quad1();
quad1.print();

在这两种情况下我都可以调用打印函数,那么这两种继承方式有什么区别,或者我在这里做错了什么?

【问题讨论】:

    标签: javascript inheritance ecmascript-6 prototype prototypal-inheritance


    【解决方案1】:

    在 JavaScript 中,它与对象所有权有关。 Object.call 不是永久所有权更改,它本质上“调用”另一个函数,所有权设置为该调用的调用函数,因此将其自己的属性(由 this 定义)传递给“拥有”函数。

    例如。

    function Polygon() {
      this.sides = 2;
      this.dimensions = "2d";
      var _this = this;
      this.print = function () {
        console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
      }
    }
    function Quad() {
      Polygon.call(this);
      this.sides = 4;
    }
    new Quad().print();
    // Outputs: 2d dimensions are easy to work with!, sides:  4
    

    通过调用Polygon.call,并以this 作为属性,它用来自Quad 的this 替换Polygon 的this 引用,但仅在调用范围内,实质上是复制对this 所做的更改在 Polygon 中,到 Quad this

    请看下面的例子:

    function Polygon(sides) {
      this.sides = sides;
      this.dimensions = "2d";
      var _this = this;
      this.print = function () {
        console.log("%s dimensions are easy to work with!, sides: ", _this.dimensions, _this.sides);
      }
    }
    function Quad() {
      Polygon.call(this);
      this.sides = 4;
    }
    const poly = new Polygon(2);
    const quad = new Quad();
    quad.print(); // 2d dimensions are easy to work with!, sides:  4
    poly.print(); // 2d dimensions are easy to work with!, sides:  2
    poly.print !== quad.print; // should return true
    

    使用Object.prototype 是不同的,因为您直接修改对象,而使用Call,您仅在该调用上调用具有隐含所有权的函数。这两个示例的不同之处在于,原型示例直接在 Quad 对象上创建了一个 Polygon 实例,而 Call 从未明确地这样做。

    两个方向各有优缺点,测试方法不同等。

    【讨论】:

    • 非常感谢您的帮助,非常感谢。
    猜你喜欢
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2012-11-07
    相关资源
    最近更新 更多