Object.prototype和bind()方法如何协同工作

时间:2016-07-01 16:59:38

标签: javascript angularjs prototype bind factory

我正在阅读关于ngInfiniteScroll的文章,我是一个关于JS的新手。 在我阅读了nfInfiniteScroll的demo之后,我很难理解为什么Reddit.nextPage已转换为Reddit.prototype.nextPage并且它已被用于{{1}包装bind() body的一部分的方法。

这是代码。

Reddit.prototype.nextPage

我刚刚理解:通过使用myApp.controller('DemoController', function($scope, Reddit) { $scope.reddit = new Reddit(); }); // Reddit constructor function to encapsulate HTTP and pagination logic myApp.factory('Reddit', function($http) { var Reddit = function() { this.items = []; this.busy = false; this.after = ''; }; Reddit.prototype.nextPage = function() { if (this.busy) return; this.busy = true; var url = "https://api.reddit.com/hot?after=" + this.after + "&jsonp=JSON_CALLBACK"; $http.jsonp(url).success(function(data) { var items = data.data.children; for (var i = 0; i < items.length; i++) { this.items.push(items[i].data); } this.after = "t3_" + this.items[this.items.length - 1].id; this.busy = false; }.bind(this)); }; return Reddit; }); ,我可以访问this对象中的属性。

仅仅是因为Reddit被分配了一个匿名函数而且我需要将匿名函数的var Reddit绑定到this的{​​{1}},所以它们指的是同一个特性

但即使没有this方法,我也可以狡猾地看到可以访问这些属性。参见:

Reddit.nextPage

我已经阅读了一些关于这个主题的文章,但没有一篇文章深入探讨:我真的很困惑。

3 个答案:

答案 0 :(得分:1)

让我们看看这些功能:

Reddit.prototype.nextPage = function() {
    // outer function
    ...    
    $http.jsonp(url).success(function(data) {
      // inner function
    }.bind(this));
  };

如果没有绑定,内部函数中的this将具有不同的属性,因为它位于另一个上下文中。但是,如果我们调用bind(this),我们会告诉内部函数使用外部函数的上下文中的this

有关详细信息,我建议this article

答案 1 :(得分:1)

我还没有访问过这篇博客文章,但我猜测它已被移动到原型上宣布的原因是让它自动包含在你的&#34; Reddit&的每个实例中#34;服务。每次创建服务时,它都将包含此方法,因为所有原型方法都会自动继承。

关于bind,每当你将一个函数作为参数传递时,当函数被执行时它将失去主上下文,这意味着它将不再被绑定到你的Reddit服务,因为它将有一个新的执行范围。因此,对this.items,this.busy和this.after的调用都将是未定义的并且会导致错误。

以下是bind(), call() and apply()的更多信息。

答案 2 :(得分:0)

this取决于上下文。一个例子:

var foo = {
  bar: function() {
    console.log(this.baz);
  },
  baz: 3
};

foo.bar(); // logs 3

但是在异步回调中,上下文消失了,使用setTimeout

的示例
var foo = {
  bar: function() {
    setTimeout(function() { console.log(this.baz); }, 0);
  },
  baz: 3
};

foo.bar(); // logs undefined or throws an error in strict mode

'this'不再属于foo。我们可以使用bind来解决这个限制:

var foo = {
  bar: function() {
    setTimeout((function() { console.log(this.baz); }).bind(this), 0);
  },
  baz: 3
};

foo.bar(); // logs 3

我们现在已将上下文绑定到foo(调用站点上的this的值),这是您的示例中正在进行的操作,this在回调中的绑定传递给成功$http.jsonp返回的承诺的处理程序。