【问题标题】:How Object.prototype and bind() method work togetherObject.prototype 和 bind() 方法如何协同工作
【发布时间】:2016-07-01 16:59:38
【问题描述】:

我正在阅读有关 ngInfiniteScroll 的信息,并且我是 JS 的新手。 当我阅读了 nfInfiniteScroll 的 demo 时,我很难理解为什么 Reddit.nextPage 已被转换为 Reddit.prototype.nextPage 并且已使用 bind() 方法来包装 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绑定到Reddit.nextPagethis,所以它们引用相同的属性?

但我可以清楚地看到,即使没有 bind() 方法,也可以访问这些属性。见:

if (this.busy) return;
this.busy = true;

我已经阅读了一些关于该主题的文章,但没有一篇深入解释它:我真的很困惑。

【问题讨论】:

    标签: javascript angularjs prototype bind factory


    【解决方案1】:

    让我们看看这些函数:

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

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

    更多信息我推荐this article

    【讨论】:

      【解决方案2】:

      我还没有访问过这篇博文,但我猜测它被移到原型上声明的原因是为了让它自动包含在你的“Reddit”服务的每个实例中。每次创建服务时都会包含此方法,因为所有原型方法都会自动继承。

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

      这里有更多关于bind(), call() and apply()的信息。

      【讨论】:

        【解决方案3】:

        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 的值),这就是您的示例中发生的情况,在传递给 promise 的成功处理程序的回调中绑定 this$http.jsonp返回。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-09
          • 2019-04-21
          • 2014-08-05
          • 2020-01-14
          • 2012-12-21
          • 2013-01-19
          • 2018-07-08
          • 2012-11-30
          相关资源
          最近更新 更多