我们有两种不同的方式在JavaScript中进行函数表达式:
命名函数表达式(NFE):
var boo = function boo () {
alert(1);
};
Run Code Online (Sandbox Code Playgroud)
匿名函数表达式:
var boo = function () {
alert(1);
};
Run Code Online (Sandbox Code Playgroud)
并且可以调用它们boo();.我真的不明白为什么/什么时候我应该使用匿名函数,何时我应该使用命名函数表达式.他们之间有什么区别?
我可以在变量中创建一个递归函数,如下所示:
/* Count down to 0 recursively.
*/
var functionHolder = function (counter) {
output(counter);
if (counter > 0) {
functionHolder(counter-1);
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,functionHolder(3);就输出了3 2 1 0.假设我做了以下事情:
var copyFunction = functionHolder;
Run Code Online (Sandbox Code Playgroud)
copyFunction(3);输出3 2 1 0如上.如果我改变functionHolder如下:
functionHolder = function(whatever) {
output("Stop counting!");
Run Code Online (Sandbox Code Playgroud)
然后functionHolder(3);会Stop counting!按预期给出.
copyFunction(3);现在给3 Stop counting!它指的是functionHolder,不是函数(它本身指向).在某些情况下这可能是理想的,但是有没有办法编写函数以便它调用自身而不是保存它的变量?
也就是说,是否可以仅更改线路,functionHolder(counter-1);以便3 2 1 0在我们呼叫时仍然通过所有这些步骤copyFunction(3);?我尝试了,this(counter-1);但这给了我错误this is …
通常,在Javascript中,当我想将匿名/内联函数作为参数传递给另一个函数时,请执行以下操作之一。
someFunctionCall(function() {
//...
});
someFunctionCall( () => {
//...
});
Run Code Online (Sandbox Code Playgroud)
但是,我最近继承了一个使用命名函数作为内联参数的代码库,如下所示
someFunctionCall(function foo() {
//...
});
Run Code Online (Sandbox Code Playgroud)
我以前从未见过这种语法。该函数似乎仍然是匿名的- foo在调用范围或被调用范围中都没有定义函数。这仅仅是样式问题,还是可以使用命名函数(foo上述)作为匿名函数来更改该程序的行为或状态?
这是专门针对NodeJS(不是基于浏览器的程序)程序的,并且我对使用函数作为参数的特定行为特别感兴趣。也就是说,欢迎跨平台和运行时提供来自行为的信息。
javascript closures anonymous-function node.js function-expression
(function test() {
test = 123;
console.log( test );
}());
Run Code Online (Sandbox Code Playgroud)
此功能在控制台中打印它的主体,但不是'123'.这种行为的原因是什么?
我对函数执行的解释失败了?
javascript scope function function-declaration function-expression
遇到一些在表达式中使用IIFE而不仅仅是普通函数的代码.
var custom_type = (function() {
return $('#myDiv').attr('custom_type');
})();
Run Code Online (Sandbox Code Playgroud)
通常我会写这样的东西:
var custom_type = function() {
return $('#myDiv').attr('custom_type');
};
Run Code Online (Sandbox Code Playgroud)
IIFE的原因是什么?我唯一能想到的是,IIFE可能custom_type只在开始时分配变量一次,而第二次可能会在每次引用变量时继续检查更新的类型.
我在块范围中定义函数时遇到了问题.考虑以下程序:
try {
greet();
function greet() {
alert("Merry Christmas!");
}
} catch (error) {
alert(error);
}
Run Code Online (Sandbox Code Playgroud)
我希望这个程序能够提醒Merry Christmas!.但是在Firefox中给了我以下内容ReferenceError:
ReferenceError: greet is not defined
Run Code Online (Sandbox Code Playgroud)
在Opera和Chrome上,它会像我预期的那样提醒问候语.
显然,Firefox会将块范围内的功能视为一段FunctionExpression时间,而Opera和Chrome将其视为一个FunctionDeclaration.
我的问题是为什么Firefox表现不同?哪种实现更符合逻辑?哪一个符合标准?
我理解JavaScript中的声明是悬而未决的,因此如果在同一范围内的两个或多个不同的块中声明相同的函数,那么就会出现名称冲突.
但是,每次声明函数时重新声明函数都不是更合乎逻辑,这样你就可以做到这样的事情:
greet(); // Merry Christmas!
function greet() {
alert("Merry Christmas!");
}
greet(); // Happy New Year!
function greet() {
alert("Happy New Year!");
}
Run Code Online (Sandbox Code Playgroud)
我认为除了解决上面描述的块范围问题之外,这将非常有用.
我刚刚了解了函数声明和函数表达式之间的区别.这让我想知道我是否在AngularJS代码中做得对.我正在遵循John Papa使用的模式,但现在它似乎与模块模式的典型JS方法不一致.John Papa在他的控制器和服务中大量使用嵌套的函数声明.这不好吗?
有没有理由支持这个:
var foo = (function() {
var bar = function() { /* do stuff */ };
return {
bar : bar
};
}());
foo.bar();
Run Code Online (Sandbox Code Playgroud)
对此:
var foo = (function() {
return {
bar : bar
};
function bar() { /* do stuff */ };
}());
foo.bar();
Run Code Online (Sandbox Code Playgroud)
我主要是一名C#开发人员,仍然习惯于JavaScript的所有细微差别.我更喜欢后一种方法,因为IIFE中的所有功能都是私有的,顶部的揭示模块模式实际上是公共部分.在C#类中,我总是在私有支持函数之前拥有我的公共属性和方法.但是,我意识到它在JS世界中可能不那么干脆.
使用后一种方法有哪些隐患(如果有的话)?
javascript module-pattern function-declaration function-expression iife
在 TypeScript 的接口和类型中使用粗箭头和非粗箭头语法声明函数之间有什么区别?
例如:
build(paramOne: string): string;
Run Code Online (Sandbox Code Playgroud)
相比:
build: (paramOne: string) => string;
Run Code Online (Sandbox Code Playgroud)
起初,我认为这会限制我实现功能的方式,但似乎并非如此。所以,我不认为它与thisES6 中的类似。但我确实注意到,当我尝试重载时,用粗箭头语法声明的那个有问题。
例如,这是不可接受的:
build: (paramOne: string) => void
build: (paramOne: number, paramTwo: string) => void
Run Code Online (Sandbox Code Playgroud)
这将给出一个错误:
Subsequent property declarations must have the same type. Property 'build' must be of type '{ (paramOne: string): string; (paramOne: number, paramTwo: string): number; }', but here has type '(params: unknown) => void
Run Code Online (Sandbox Code Playgroud)
但这没关系:
build(paramOne: string): string;
build(paramOne: number, paramTwo: string): number;
Run Code Online (Sandbox Code Playgroud)
那么,这两种语法是否相同?是否有任何差异或场景我应该使用另一种?
我正在浏览这篇关于函数声明和函数表达式之间差异的博客.
它给出了这两个例子.他们将第一个称为"匿名函数表达式",将第二个称为"命名函数表达式".
// anonymous function expression
var a = function(){
return 3;
}
// named function expression
var b = function bar(){
return 3;
}
Run Code Online (Sandbox Code Playgroud)
我在Chrome的JS控制台中测试了这两个,我看到以下内容:
a()
=> 3
b()
=> 3
bar()
=> bar is not defined
Run Code Online (Sandbox Code Playgroud)
我的问题是:在第二个函数表达式声明中,"bar"的重点是什么?一般来说,为什么要使用命名函数表达式?
为什么这不能使用函数声明,但它使用函数表达式完美地工作?假设唯一的区别是浏览器如何将它们加载到执行上下文中.
function foo(event){
console.log('in foo');
}
$('.btn').on('click',foo(event));
$.ajax({
beforeSend:function(){
$('btn').unbind('click');
},
success: function(){
$('btn').bind('click', foo(event));
}
});
Run Code Online (Sandbox Code Playgroud)
使用函数表达式它很有用:
var foo = function(event){
console.log('in foo');
}
Run Code Online (Sandbox Code Playgroud) javascript jquery event-handling function-declaration function-expression
这是对你在john resig的Learning Advanced Javascript应用程序中找到的内容的改编.
var math = {
fact: function fact(n){
return n > 0 ? n * fact(n-1): 1;
},
fact1: function (n) {
return n > 0? n * math.fact1(n-1) : 1;
}
};
console.log(math.fact(5)); // 120
console.log(math.fact1(5)); // 120
var o = {
x: math.fact,
y: math.fact1
};
math = {};
console.log(o.x === undefined); // false
console.log(o.y === undefined); // false
console.log(o.x(5)); // 120
console.log(o.y(5)); // Uncaught TypeError: math.fact1 is not a function
Run Code Online (Sandbox Code Playgroud)
人们会期望o.x(5)应该抛出错误,但它会执行.为什么?
如果(function foo(){})是一个表达式,由于'context'为"(括号)"是一个分组运算符,分组运算符只能包含一个表达式.
这导致了这个问题,您能否在IIFE中声明一个函数,或者它仍然算作一个函数表达式?
javascript function function-declaration function-expression iife
javascript ×11
function ×5
iife ×3
closures ×2
scope ×2
jquery ×1
node.js ×1
overloading ×1
recursion ×1
typescript ×1