javascript命名函数表达式-作用域可访问性
javascript named function expressions - scope accessibility
我正在关注John Resig的JS忍者的秘密幻灯片,我发现了一些我不太清楚的东西。以下代码定义了命名函数表达式:
var ninja = function myNinja(){
console.log(myNinja); // function myNinja() {...}
};
myNinja; // undefined
正如我所看到的,在当前作用域(假设它是全局的)中,ninja
是引用命名函数myNinja
的变量。ninja
变量在作用域中是可访问的——这很清楚,但myNinja
在作用域内是不可访问的(但它可以在自己的函数内访问)。为什么?
如果我定义一个函数(不是使用函数表达式,而是函数声明):
function Cheese() {
console.log(Cheese);
}
那么它在当前范围内是可访问的。我知道这就是这样的——但有人能解释为什么吗?
在他的书《JavaScript忍者的秘密》中,John Resig对这个概念做出了精彩的解释。
http://jsninja.com/
以下是这本书的引文:
4.2.4内联命名函数
<script type="text/javascript">
var ninja = function myNinja(){
assert(ninja == myNinja, "this is named two things at once!");
};
ninja();
assert(typeof myNinja == "undefined",
"But myNinja isn't defined outside of the function.");
</script>
这个列表提出了关于内联的最重要的一点函数:即使可以命名内联函数,这些名称也是仅在函数本身中可见。
还记得我们在第3章中谈到的范围界定规则吗内联函数名的作用有点像变量名,它们的作用域是仅限于声明它们的函数
3.2.1.范围界定和功能
变量声明的范围从声明点到声明它们的函数的末尾,而不管块嵌套。
如果你想了解更多关于这个概念的信息,这本书将对你有所帮助。
为什么?
函数表达式每次求值时都会创建一个新的函数对象。这个结果一开始是无关紧要的。但是…
var ninja;
// myNinja; - what would you expect it to be here?
for (var i=0; i<5; i++)
ninja = function myNinja(){
console.log(myNinja);
};
// myNinja; - *which one* would you expect it to be here?
ninja();
对ninja()
的调用是显而易见的,它引用了最后分配给该变量的函数。console.log
中的myNinja
引用当前函数对象-它在自己的范围内。
但是myNinja
标识符在函数本身之外是不明确的。
相反,函数声明是挂起的,并且可以从整个范围访问。其标识符唯一地引用在范围初始化中创建一次的单个函数对象。
想象一下,当你简单地定义一个函数(cheese)时,你告诉当前范围——"我想让你知道这个函数,它的名字是cheese。当你使用var忍者时,你现在处理的是忍者范围,告诉它基本上相同的事情。所以现在你的新功能(myNinja)只在当前(ninja)范围内知道。。。
Name是函数对象的一个属性。如果要在调试器中检查Function实例,则会在其上看到一个name
属性。如果是在全局范围中定义的函数,则name
的值会自动用作引用它的window
对象。
在内联函数的情况下,您将定义引用该函数的属性的名称。JS引擎不需要使用Function实例中的name
属性。
- 从ng模板访问作用域
- 访问多个指令的隔离作用域
- 如何在隔离作用域指令中访问此作用域变量
- 访问Javascript对象-Node.js的作用域问题
- 当指令中已经给定作用域时,如何访问控制器中声明的函数
- 插槽:访问作用域变量
- 从ES6中的函数表达式访问类作用域
- 跨不同作用域访问函数
- AngularJS$作用域在函数之外不可访问
- 使用模块模式时访问父作用域中的变量
- 从jQuery.ech()函数访问外部作用域
- 以新模式访问作用域形式ng repeat
- 作用域访问-Javascript
- 如何从全局作用域访问函数中的变量?
- 如何从不同的对象作用域访问可观察对象
- 如何从两次或三次嵌套的ng-repeat作用域访问控制器的作用域
- 我如何从上层作用域访问变量- javascript
- 从外部(即定义闭包的作用域)访问闭包内部定义的var
- 从内部函数的父作用域访问数组元素
- 从指令作用域访问Angular工厂