传递函数作为参数-数组表示法
Passing a function as parameter - array notation
将函数传递给各种AngularJS方法的推荐方法是使用AngularJS文档中称为数组表示法的语法。
你应该这样做:
app.controller("MyCtrl", ['$scope', function($scope){
$scope.someData = "Array notation";
}]);
而不是:
app.controller("MyCtrl", function($scope){
$scope.someData = "non-array notation";
});
因为AngularJS依赖注入和最小化的工作方式。
我想知道传递函数作为参数的第一种方式是JavaScript标准中提到的语法吗?我还没有设法找到任何关于"数组符号"在这种情况下在网络上。
这只是一个约定——但考虑得很周到,因此在Angular中一直在使用。你看,一个函数——一个模块——可以只有一个依赖项(就像你的例子中那样),也可以有很多依赖项(从两个开始),或者根本没有依赖项。所以我们需要一些解决方案来解决所有的情况。
朴素的方法是将所有深度指定为函数参数(第二个示例)。现在,可以通过分析函数源代码来提取(并注入)它们。优点:编写的代码绝对最少(无论如何,您必须指定所有深度的名称)。缺点:1)基于反射(它永远不会很快),2)当脚本被最小化时(所有参数的名称都被转换)会中断。
这些缺点已经够糟糕的了,所以必须有另一种方法。但是,我们不想去掉参数列表(这些深度仍然必须以某种方式在函数中处理,对吧?)但现在很明显,单一的列表是不够的——它必须在某个地方复制。
这就是Array(元素的有序序列)非常方便的地方。现在注入器只需要分离该数组的最后一个元素就可以得到完整的深度列表。那些是字符串,不是变量,所以它们不会被minifier修改。更棒的是,现在我们不需要分析签名了,所以注入器工作起来快了一点。
从理论到实践:这就是这两种方法在Angular 1中的实现方式。x DI模块:
function annotate(fn, strictDi, name) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn === 'function') {
// first approach: only function is passed, we need to analyze the args list
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
if (strictDi) {
if (!isString(name) || !name) {
name = fn.name || anonFn(fn);
}
throw $injectorMinErr('strictdi',
'{0} is not using explicit annotation and cannot be invoked in strict mode', name);
}
// get rid of comments, it's possible to have those inside `()`
fnText = fn.toString().replace(STRIP_COMMENTS, '');
// extract arguments
argDecl = fnText.match(FN_ARGS);
// push those into injector
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
arg.replace(FN_ARG, function(all, underscore, name) {
$inject.push(name);
});
});
// ... and that took some time
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
// second approach: an array is passed
last = fn.length - 1;
// make sure its last element is a function
assertArgFn(fn[last], 'fn');
// use all but the last element as list of deps
$inject = fn.slice(0, last);
// ... and that's all, believe it or not!
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
如您所见,第一个if
分支是用于旧的方式-深度表示为函数参数。第二个(更容易阅读和执行)-用于放置在数组中的深度和函数(函数是最后一个元素)。
它只是一个包含字符串和函数的数组。
对于AngularJS来说,符号本身并没有什么神奇之处。函数可以是数组成员,就像其他数据类型一样。- 如何避免“;使用数组文字表示法“;以下javascript代码中的jslint错误
- 如何在ember数据模型中表示数组
- 使用数组表示法对多个字段执行jQuery日期选择器
- 如何使用不可变表示此数组重新排序示例
- 数组表示形式内的字符串IndexOf
- 由数组数组表示的表;不起作用
- 使用来自 JSON 对象的数组表示法进行多级属性检索
- 数组表示法操作顺序
- 用 JS 数组表示不确定大小的 2d 空间 - 负索引
- 将字符串数组表示形式转换回数组
- 为什么使用数组表示法而不是点表示法来检查变量是否存在
- 在webpack中创建多个块时,数组表示法和对象表示法之间的区别是什么
- 使用[]数组表示法访问属性
- 传递函数作为参数-数组表示法
- 我应该在Angular中使用数组表示法吗
- 如何在JavaScript中比较两个数组,并返回一个新的数组表示匹配
- 知道何时使用数组表示法将属性设置为对象
- 数组表示null,即使正在设置索引
- 如何选中由二维数组表示的所有复选框
- 在javascript中使用数组表示法给子对象字段赋值