ES6和Knockout的{this'范围

时间:2015-07-13 13:28:50

标签: javascript knockout.js ecmascript-6

使用ES6时,我遇到了'this'范围的问题。

以下是我与BabelJS original and transpiled code的链接。

调用函数从数组中删除项时,“this”的范围未定义。

如何在不重新定义( let self = this )的情况下实现此目的?

"use strict";

var _createClass = (function() {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }
  return function(Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    return Constructor;
  };
})();

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var Point = (function() {
  function Point() {
    var _this = this;

    _classCallCheck(this, Point);

    this.myArray = ko.observableArray([1, 2, 3, 4]);
    this.removeFromArrayWithArrowFunction = function(value) {
      _this.myArray.remove(value);
    };
  }

  _createClass(Point, [{
    key: "removeFromArray",
    value: function removeFromArray(value) {
      this.myArray.remove(value);
    }
  }]);

  return Point;
})();

ko.applyBindings(new Point());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span data-bind="text: ko.toJSON(myArray)"></span>
<h2>Issues with this scoping when using a regular Function</h2>
<ul data-bind="foreach: myArray">
  <li>
    <a href="#" data-bind="text: $data, click: $parent.removeFromArray"></a>

  </li>
</ul>

<h2>Works as expected using an arrow function</h2>
<ul data-bind="foreach: myArray">
  <li>
    <a href="#" data-bind="text: $data, click: $parent.removeFromArrayWithArrowFunction"></a>

  </li>
</ul>

1 个答案:

答案 0 :(得分:2)

如果您在绑定中直接使用viewmodel函数,那么就像Jeff Mercado解释的那样,你会失去this的上下文。 Arrow functions capture the this value of the enclosing context,所以如果您使用箭头函数表示法,则不必担心var self = this

所以改变以下内容:

removeFromArray(value) {
  this.myArray.remove(value);
}

分为:

removeFromArray = (value) => {
  this.myArray.remove(value);
}

它应该可以正常工作。

See babel