underscore中的invoke函数的定义是:
1 _.invoke= function(obj, method){ 2 var args = slice.call(arguments,2); 3 var isFunc = _.isFunction(method); 4 return _.map(obj,function(value){ 5 return (isFunc ? method : value[method]).apply(value, args); 6 }); 7 };
我的调用方式是:
1 console.log(_.invoke([[5, 1, 7], [3, 2, 1]], 'sort'));
最终的运行结果是[[1, 5, 7], [1, 2, 3]]。
因为自己传入的‘sort’非函数,故在invoke函数的isFunc为false,故invoke返回的函数其实是:
1 _.map(obj,function(value){ 2 return value[method].apply(value, args); 3 });
通过跟踪我发现在运行的时候,当运行到value[method].apply(value, args);时,某一时刻实际的代码是[5,1,7]['sort'].apply([5,1,7],[]),重点来了,在这里,编译器直接把[5,1,7]['sort']变成了function sort(){}!
于是我尝试单独运行console.log([]['sort']); 发现非但没报错,而且还被解析成了function sort(){}。但如果把这里的sort换为非js关键字的字符串,比如改为console.log([]['aaa']); 运行结果就是undefined。难道这是另一种将js自带方法从字符串转换为函数的方法吗?
想不通为什么会这样,请知道的朋友告知一下,非常感谢!
[]是一个数组,数组又是一个对象,[5,1,7]['sort']是执行了数组 [5,1,7] 的 sort 方法