Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 应用于函数引用/作用域的原型继承和函数引用_Javascript_Angularjs_This_Pass By Reference_Prototype Programming - Fatal编程技术网

Javascript 应用于函数引用/作用域的原型继承和函数引用

Javascript 应用于函数引用/作用域的原型继承和函数引用,javascript,angularjs,this,pass-by-reference,prototype-programming,Javascript,Angularjs,This,Pass By Reference,Prototype Programming,假设我有以下两条指令: angular.module('demo').directive('functional', [function (){ var idempotentMethods = ['idempotentMethod', 'otherIdempotentMethod']; return { restrict: 'E', scope: { 'demoObject': '=' }, templateUrl: 'directive.ht

假设我有以下两条指令:

angular.module('demo').directive('functional', [function (){
  var idempotentMethods = ['idempotentMethod', 'otherIdempotentMethod'];
  return {
    restrict: 'E',
    scope: {
      'demoObject': '='
    },
    templateUrl: 'directive.html',
    link: function (scope){
      for(var i = 0; i < idempotentMethods.length - 1; i++){
        scope[idempotentMethods[i]] = function(){
          scope.demoObject[idempotentMethods[i]]();
        }
      }
    }
  }
}]);

angular.module('demo').directive('nonFunctional', [function (){
  var idempotentMethods = ['idempotentMethod', 'otherIdempotentMethod'];
  return {
    restrict: 'E',
    scope: {
      'demoObject': '='
    },
    templateUrl: 'directive.html',
    link: function (scope){
      for(var i = 0; i < idempotentMethods.length; i++){
        scope[idempotentMethods[i]] = scope.demoObject[idempotentMethods[i]];
      }
    }
  }
}]);
在函数指令中,当触发scope.idempotentMethod()时(通过
ng单击
或其他方式),将调用错误的工厂方法

在非功能指令中,它触发

  TypeError: undefined is not a function
    at Scope.angular.extend.idempotentMethod
    at $parseFunctionCall
    at callback
    at Scope.$eval
在工厂里的方法。 这意味着两件事。 1) 函数引用是绑定的(如预期),但是只有最后一个函数引用是绑定的。 2)
参考不正确。在工厂方法中打印出
似乎证实了这一点,非功能指令产生范围,而功能指令产生资源

是什么导致了这两种行为?为什么此引用绑定不正确?为什么调用了错误的函数


演示问题的一个例子:

我认为这是您设置闭包的方式:

function createBound(){
  var fn = function(){console.log('this is:',this);}
  ,i = -1//ret items are set using the value i inside createBound
    //by the time we call the function the value of i is 2
  ,ret = [];
  for(i = 0; i < 2; i++){
    ret.push(function(){
      console.log('i is:',i);//says 2 every time
      fn.call({hello:'world'});
    });
  }
  return ret;                                  
}
var bound = createBound();
bound[0]();
bound[1]();
函数createBound(){
var fn=function(){console.log('this:',this);}
,i=-1//ret项是使用createBound中的值i设置的
//当我们调用函数时,i的值是2
,ret=[];
对于(i=0;i<2;i++){
ret.push(函数(){
log('i是:',i);//每次都说2
fn.call({你好:'world'});
});
}
返回ret;
}
var-bound=createBound();
束缚[0]();
束缚[1]();
正确的方法:

function createBound(){
  var fn = function(){console.log('this is:',this);}
  ,i = -1
  ,ret = [];
  for(i = 0; i < 2; i++){
    ret.push(
      (function(i,fn){//IIFE returning a function with correct i and fn
        //the value of i and fn that are passed are used in the returned closure
        //scope is within this IIFE, not within createBound
        return function(){
          console.log('i is:',i);//says: 0,1
          fn.call({hello:'world'});
        };
      }(i,fn))//end of IIFE where i and fn are passed to create a new closure
    );
  }
  return ret;                                  
}
var bound = createBound();
bound[0]();
bound[1]();
函数createBound(){
var fn=function(){console.log('this:',this);}
,i=-1
,ret=[];
对于(i=0;i<2;i++){
后推(
(函数(i,fn){//iLife返回具有正确i和fn的函数
//传递的i和fn的值用于返回的闭包
//作用域在此IIFE内,而不是CreateBund内
返回函数(){
log('i是:',i);//表示:0,1
fn.call({你好:'world'});
};
}(i,fn))//IIFE的结束,其中i和fn被传递以创建新的闭包
);
}
返回ret;
}
var-bound=createBound();
束缚[0]();
束缚[1]();
[更新]

在代码中,要传递正确的闭包,可以执行以下操作:

  for(var i = 0; i < idempotentMethods.length - 1; i++){
    scope[idempotentMethods[i]] = (function(i,idempotentMethods){
      return function(){
        scope.demoObject[idempotentMethods[i]]();
      };
    }(i,idempotentMethods));
  }
for(var i=0;i

请注意,我没有计算到幂等方法的末尾,这就是为什么在触发ng click时代码执行
幂等方法[idempotenthods.length-1]

您是否在
scope.demoObject[idempotentMethods[i]]之前尝试过
console.log(i)
我认为你把闭包设置错了,如果幂等方法有不止一个元素,那可能会导致一些问题。这是对第一个问题的极好解释。我的头受伤了:(.有没有想过为什么直接传递函数引用的另一种方法不起作用,以及我如何强制更正此引用?@AbrahamP当您执行$scope.someFunction=someFunction时,此函数在someFunction中的值将为$scope。这就是您传递闭包或使用bind的原因。@AbrahamP使用可用于传递函数的代码更新了答案。)e正确关闭。
  for(var i = 0; i < idempotentMethods.length - 1; i++){
    scope[idempotentMethods[i]] = (function(i,idempotentMethods){
      return function(){
        scope.demoObject[idempotentMethods[i]]();
      };
    }(i,idempotentMethods));
  }