Javascript 这个函数表达式是如何工作的?
在声明正确之前不能使用Function express?但也传递给按键功能。这魔法是怎么发生的 我正在编写代码,在查看时注意到了它Javascript 这个函数表达式是如何工作的?,javascript,hoisting,Javascript,Hoisting,在声明正确之前不能使用Function express?但也传递给按键功能。这魔法是怎么发生的 我正在编写代码,在查看时注意到了它 var controller = (function(budgetCtrl, UICtrl){ var setUpEventListeners = function(){ //CTRLADDITEM is called below document.querySelector(DOM.inpu
var controller = (function(budgetCtrl, UICtrl){
var setUpEventListeners = function(){
//CTRLADDITEM is called below
document.querySelector(DOM.inputBtn).addEventListener('click', **ctrlAddItem**);
document.addEventListener('keypress', function(e){
if(event.keyCode === 13 || event.which === 13){
**ctrlAddItem();**
}
});
}
var **ctrlAddItem** = function(){
updateBudget();
}
};
}
})(budgetController, UIController );
这被称为,它在Javascript以及其他语言(如Go)中相当常见。这是一个简单的版本
(function() {
alert('invoked immediately');
})();
此代码将立即运行。注意:在定义它之前,不会调用它。它由后面的括号调用,该括号直接出现在定义它之后。这和做这件事完全一样
function doSomething() {
}
doSomething();
我们只是将函数内联到括号中,然后调用它()
,而不是按名称调用它
如果将结果分配给变量,则其工作方式与预期相同,即分配函数的结果
// these two are equivalent
var result = (function () {
return 5;
})();
var result = 5;
现在,result
中的值将等于5
我们为什么要使用它们?
最常见的是,我们使用它们来隔离代码的范围,以防止它污染全局范围。例如,如果这是您的应用程序代码
function MyApp() {
}
您现在通过创建window.MyApp
污染了全局范围。如果您使用的第三方库在全局作用域上也提供了名为MyApp
的函数,它将覆盖您的函数。为了防止这种情况,我们可以
(function(window) {
function MyApp() {}
MyApp();
})(window);
现在,MyApp
未连接到该窗口,我们仍然可以访问该窗口
兔子洞下更远的地方
必须先将函数从声明转换为表达式,然后才能立即调用它。要执行此操作,请将其括在括号中
这不起作用
function (){
// do something
}()
~function () {
}()
+function () {
}()
-function () {
}()
void function () {
}()
这确实有效(由于括号)
也可以使用任何一元运算符代替括号所有这些工作
function (){
// do something
}()
~function () {
}()
+function () {
}()
-function () {
}()
void function () {
}()
你所拥有的是:
// Pass ctrlAddItem
document.querySelector(DOM.inputBtn).addEventListener('click', ctrlAddItem);
// Include closure to ctrlAddItem in function expression
document.addEventListener('keypress', function(e){
if(event.keyCode === 13 || event.which === 13){
ctrlAddItem();
}
});
// later...
var ctrlAddItem = function(){ /* whatever */ }
因此,ctrlAddItem被声明,因此在执行任何代码之前,它的值为undefined。在addEventListener中使用时,其值仍然未定义
但是,在外部函数完成之前(以及在调用侦听器之前),会为ctrlAddItem分配一个值。因此,在调用侦听器时,它是一个(对a的引用)函数。是
easy===looooong
?请将代码减少到演示问题所需的最小值。很难判断“此函数”是什么。当您实际触发事件处理程序时,它将被声明。查找IIFE(立即调用的函数表达式)。代码太多,即使删除了几十行无用的空行。我想我明白你的意思了。我在代码笔中做了一个测试,所以基本上IIFE调用了所有的代码,带有尾随()-所以当安装事件监听器执行时,IIFE中的所有代码都已经发生了-正确吗?:是的,正确。所有这些代码都会立即运行。在javascript控制台中复制并粘贴我的第一个示例,警报将立即触发。您已经在一条语句中声明并调用了该函数。感谢您的帮助。我做了一些测试,虽然我知道IFFE是什么,但它似乎不起作用,为什么@Charlie Martin:(function(){document.getElementById('btn').addEventListener('click',Martin);var Martin=function(){alert('called instally')};}();没关系,我做了一些测试,发现了。调用a.init()时整个函数都已运行感谢您的帮助在Charlie Martin执行了一些测试--var a=(function(){function setUp(){document.getElementById('btn')。addEventListener('click',Martin);}var Martin=function(){alert('called instally')};return{init:function(){setUp(){setUp();}}; a、 init();您的第一个示例有一个小问题,那就是您在将函数martin
传递给addEventListener
之后定义了它,因此您确实传递了它undefined
。这是javascript中的一个问题,这是另一个蠕虫的例子:)试试这个:
// these two are equivalent
var result = (function () {
return 5;
})();
var result = 5;