知道JavaScript函数表达式和函数声明,但这是什么?命名函数表达式?
可能重复:知道JavaScript函数表达式和函数声明,但这是什么?命名函数表达式?,javascript,oop,Javascript,Oop,可能重复: 我知道函数声明和表达式之间的差异,但是我遇到了涉及函数名的代码,我想了解在运行它时会发生什么: var abc = function def() { console.log("Wait! What??"); } 我知道这不是JavaScript的一种方式,但我只想知道几件事: abc的情况如何?为什么有效abc可以调用,但不能调用def,为什么 它是函数声明还是表达式 def是未定义的-为什么?如果它应该是,有吗 内存泄漏 为什么abc.prototype是函数def
我知道函数声明和表达式之间的差异,但是我遇到了涉及函数名的代码,我想了解在运行它时会发生什么:
var abc = function def() {
console.log("Wait! What??");
}
我知道这不是JavaScript的一种方式,但我只想知道几件事:
abc
可以调用,但不能调用def
,为什么def
是未定义的
-为什么?如果它应该是,有吗
内存泄漏abc.prototype
是函数def
只有当解释器到达代码的行时,才会加载函数表达式 这意味着:
abc();
var abc = function() {
console.log("Wait! What??");
}
不起作用,但是:
def();
function def() {
console.log("Wait! What??");
}
威尔
现在在您的示例中,您可以访问def
,但只能访问函数本身内部
var abc = function def() {
console.log(def);
}
abc();
// Logs:
//function def() {
// console.log(def);
//}
这是一个2
函数表达式也可以有名称;函数表达式的名称仅在函数body1的作用域中。(由于ECMAScript第5版不推荐参数。被调用方
,因此这是编写递归“匿名”函数的唯一简单方法。)
因为它是一个函数表达式,所以名称可能不会在外部范围中引入新的绑定
此外,所有函数都是JavaScript中的对象。在f(…)
中,在使用(…)
进行“调用”之前对f
进行评估;如果f
未对函数求值,则抛出错误。这就是回调函数可以用变量命名并作为参数传递的原因
此外,检查关于原型的假设/断言:
var abc = function def() {}
abc.prototype === abc // -> false
abc.name // -> "def"
我看Bergi的答案 2.如何轻松辨别哪个是哪个 语法规则仅允许在函数声明为时将
function..
解析为函数声明,尽管大多数引擎仍会[错误地]将函数声明解析为函数声明。SourceElement产品仅发生在程序的顶级“块”或函数的顶级“块”上
在任何情况下,只要有函数..
出现在需要的位置,它就会被解析为函数表达式。所有解析为函数表达式的示例:
// Can only assign values: Statements do not have values!
var f = function () {}
var g = function gName () {} // see Bergi's answer
// Can only pass values: Statements do not have values!
doIt(function () {}) // callback / "anonymous function"
// IIFE: Immediately-Invoked Function Expression
;(function () {})() // standard IIFE
;(function () {} ()) // alternative standard IIFE
;+function () {} () // curious way to write an IIFE
// basically you can use any unary operator to turn it into an expression not only
// + but also - ! ~ and so on which will modify the return value accordingly
关键是在上述每一种情况下,function..
出现在需要表达式的语法位置,因此被解析为函数表达式。(上面几行开头的分号避免了ASI的“歧义”,这是我喜欢的不使用分号的写作风格所必需的。)
不过<代码>;函数(){}()和;函数f(){}()
都是无效语法-为什么?;-) 这是一个n。这可能的用途是:
var abc = function def() {
def.test = 'Wait!'; //< sort of a static property
console.log(def.test+" What??");
}
var abc=函数def(){
def.test='Wait!';//<类似于静态属性
控制台日志(定义测试+“什么?”);
}
但是。它是一个命名函数表达式 与函数声明相反,函数表达式的标识符不是必需的 您的函数
def
不会立即被调用-整个函数传递给abc
,需要明确地调用abc()
ES5规范的第1部分说明了如何构建命名函数表达式。阅读关于如何构建命名函数表达式的第三条产生式规则
注意:FunctionExpression中的标识符可以从
在FunctionExpression的FunctionBody中允许函数
递归地调用自己。但是,与函数声明不同
FunctionExpression中的标识符不能从中引用,并且不能引用
不影响包含FunctionExpression的范围
所有最近的浏览器都能正确处理这个问题,所以你不必担心内存泄漏或其他奇怪的事情(错误的处理只在旧的IE中出现)
abc怎么了
它包含一个函数对象。如果您不使用它,它将被垃圾收集
为什么有效
为什么不?什么“有效”
abc可以调用,但不能调用def,为什么
这只适用于外部,不适用于IE。见下文
它是函数声明还是表达式
它是一个函数表达式。您可以很容易地看到,因为它是赋值表达式的一部分;声明总是需要位于顶层(函数或全局代码)
def未定义-为什么
仅从外部。函数表达式不创建变量。“def”是函数的名称,在函数内部也是函数的引用。这允许递归,例如不使用任何外部变量
var abc = function def() {
def === abc; // true
def.name; // "def"
}
abc();
def; // undefined
如果应该是,是否存在内存泄漏
是的,在Internet Explorer中。它使用该代码创建两个不同的函数。有关详细信息,请参阅
为什么abc.prototype是函数def
它不是。它只是一个对象。它可能在控制台中以该名称显示,因为它属于名为“def”的函数。它是一个命名函数表达式。
def
可以在函数内部使用def
来引用它自己。不过要注意浏览器的怪癖(即)您可能还没有读过这些问题及其答案:并且应该为您提供所有答案。我不认为这个问题是一个骗局,因为它专门询问变量名和函数名不同的情况(即使它是由其中一个问题的答案之一回答的)1.这不是重复的2.已经添加的问题