当一个变量等于一个函数时,这意味着什么
What does it mean when a variable equals a function?
可能重复:
JavaScript:var functionName=function(){}vs function functionName(){}
在JavaScript中,将变量定义为函数的目的是什么?我以前见过这个惯例,但并不完全理解
例如,在脚本中的某个时刻,函数被调用如下:
whatever();
但是,我希望看到一个名为whatever
的函数,如下所示:
function whatever(){
}
相反,我会看到一个名为whatever
的变量,它被定义为一个函数,如下所示:
var whatever = function(){
}
这样做的目的是什么?为什么要这样做而不只是命名函数?
注意:请参阅答案末尾的更新,块内的声明变为有效(但如果您不使用严格模式,则相当复杂)。
原因之一:
var whatever;
if (some_condition) {
whatever = function() {
// Do something
};
}
else {
whatever = function() {
// Do something else
};
}
whatever();
您可能会在库的初始化中看到这样的代码,该库必须处理实现差异(例如web浏览器之间的差异,即IE的attachEvent
与标准addEventListener
之间的差异)。你不能用函数声明做等效的事情:
if (some_condition) {
function whatever() { // <=== DON'T DO THIS
// Do something
}
}
else {
function whatever() { // <=== IT'S INVALID
// Do something else
}
}
whatever();
它们没有在控制结构中指定,所以JavaScript引擎可以做他们想做的事情,不同的引擎做了不同的事情(编辑:再次,请参阅下面的注释,它们现在已指定。)
另外,之间有很大的区别
var whatever = function() {
// ...
};
和
function whatever() {
// ...
}
第一个是函数表达式,当代码在上下文的逐步执行中(例如,它所在的函数或全局代码的逐步执行)达到该点时,就会对它进行求值。它还产生了一个匿名函数(引用它的变量有一个名称,但函数没有,这对帮助您的工具帮助您有意义)。
第二个是函数声明,它在进入上下文时进行评估,然后执行任何逐步代码。(有些人称之为"提升",因为源中较低的东西比源中较高的东西发生得更早。)该函数也有一个恰当的名称。
所以考虑一下:
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "function"
function bar() {
}
}
而
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "undefined"
var bar = function() {
};
}
在第一个示例中,使用声明,在运行doSomething
和其他逐步代码之前处理声明。在第二个例子中,因为它是一个表达式,所以它是作为逐步代码的一部分执行的,所以函数没有在上面定义(变量在上面定义,因为var
也是"提升的")。
最后:目前,你不能在一般的客户端web内容中做到这一点:
var bar = function foo() { // <=== Don't do this in client-side code for now
// ...
};
您应该能够做到这一点,它被称为命名函数表达式,它是一个为函数命名的函数表达式。但是各种各样的JavaScript引擎在不同的时候都犯了错误,IE直到最近仍然犯了很大的错误。
ES2015更新+
从ES2015(又名"ES6")开始,块中的函数声明被添加到规范中。
严格模式
在严格模式下,新指定的行为简单易懂:它们的范围是发生它们的块,并被提升到它的顶部
所以这个:
"use strict";
if (Math.random() < 0.5) {
foo();
function foo() {
console.log("low");
}
} else {
foo();
function foo() {
console.log("high");
}
}
console.log(typeof foo); // undefined
(注意对函数的调用是如何在块内的函数之上的。)
本质上等同于:
"use strict";
if (Math.random() < 0.5) {
let foo = function() {
console.log("low");
};
foo();
} else {
let foo = function() {
console.log("high");
};
foo();
}
console.log(typeof foo); // undefined
松散模式
松散模式行为要复杂得多,而且在理论上,它在web浏览器中的JavaScript引擎和web浏览器中而非的JavaScript引擎之间有所不同。我不会在这里介入。不要这么做。如果你坚持在块中声明函数,请使用严格模式,在这种模式下它们是有意义的,并且在不同环境中是一致的。
这是为了将函数存储在变量中,例如将它们作为参数传递给其他函数。一个有用的例子是编写异步函数,这些函数作为参数进行回调
var callback = function() { console.log('done', result)}
var dosomething = function(callback) {
//do some stuff here
...
result = 1;
callback(result);
}
由于函数是javascript中的对象,因此您也可以使用属性和方法来扩展它们。
JavaScript中的函数是对象;换句话说,它们是值。因此,无论函数是如何定义的,您都可以始终设置一个变量来引用函数:
function foo() { ... }
var anotherFoo = foo;
anotherFoo(); // calls foo
函数是可以用作对象属性、函数参数、数组元素以及常规值在JavaScript中可以执行的任何其他操作的值。它们是对象,也可以有自己的属性。
当您将一个函数分配给一个变量时,您可以将其作为参数传递给其他函数,还可以扩展它以利用Javascript的对象模型。
如果在函数内使用"var"声明函数变量,则只能在该函数内访问变量。当您退出函数时,变量将被销毁。这些变量称为局部变量。在不同的函数中可以有具有相同名称的局部变量,因为每个局部变量只能由声明它的函数识别。
- 基于窗口宽度jquery的函数的替代方法是什么
- 如果在构造函数中有“返回”,则在 JavaScript 中的新运算符中做了什么
- 未捕获的类型错误:topFrame.window.changeSelectedBarStyle不是函数,原因是什么
- 什么'这是从第三个函数上的async 1st函数获得结果的更好方法
- 在递归生成器函数中,yield后面的*(星号/星号)语法意味着什么
- 在什么情况下需要同时使用compile&链接函数的角度
- 当一个重要的构造函数参数丢失时应该发生什么
- 当绑定到AngularJS中的函数时,会在后台发生什么
- 缓存!saveLocations()和addLocation()函数有什么区别
- 函数(i,val)在javascript中是什么意思
- 鉴于 for..在构造中,库提供的函数(如 jQuery.map() 或 _.each())有什么用
- 如果 JS 中的函数是一流的,那么在定义它们之前允许调用它们是什么
- undercore.js_.tap()函数什么是方法链
- 淘汰抛出消息:类型错误:
不是一个函数.什么意思 - JavaScript 函数什么是范围以及为什么使用 $
- jQueryAJAX函数什么都没做
- 用".then"链接bluebird中的异步函数.什么是最好的方法
- 为什么这个函数什么也不返回?
- 将参数传递给函数.什么'It’他错了
- 我有节点JS错误的日期函数什么地方出了问题