foo()和function()之间的区别{foo(); }

gvl*_*lax 8 javascript

使用匿名函数包装函数有什么好处吗?我的意思是一个特例:

function asyncFuntion(callback) {
    setTimeout(callback, 6000);
};

asyncFuntion(function() {
    console.log('Calling after 6 s.');
});   
Run Code Online (Sandbox Code Playgroud)

以及包装功能:

function asyncFuntion(callback) {
    setTimeout(function() {
        callback();
    }, 6000);
};

asyncFuntion(function() {
    console.log('Calling after 6 s.');
});
Run Code Online (Sandbox Code Playgroud)

在这两种情况下输出都是相同的.那有什么区别吗?第二个版本是我发现的学习js.我知道当我们需要闭包时这样的表格很有用但是在这里?

And*_*y E 11

第二种形式允许您传递参数callback,而第一种形式则不允许.

// 1st form
setTimeout(callback("This doesn't work as you might expect"), 6000);

// 2nd form
setTimeout(function() {
    callback("This works");
}, 6000);
Run Code Online (Sandbox Code Playgroud)

如果你没有传递参数,那么包装函数没有任何优势.


为了更加彻底,Function.prototype.bind可以用第一种形式帮助我们:

setTimeout(callback.bind(this, "This works fine too"), 6000); 

// Even with Richard JP Le Guen's example by specifying the thisObj
setTimeout(customObj.alert.bind(customObj), 6000);
Run Code Online (Sandbox Code Playgroud)

但是,您需要将此方法提供给不支持该事件的浏览器(即Opera,Safari和IE 8,7,6).可以在MDN文档页面上找到用于填充方法的代码.

  • `setTimeout(callback.bind(this,'this works aswell'),6000);` (2认同)

Ric*_*uen 5

在匿名函数中包装函数可以避免this关键字的复杂化.(在quirksmode上阅读它们)

例如:

function CustomObject() {
    this.msg = "Hello world from my custom object";
    this.alert = function() {
        alert(this.msg);
    };
}

var customObj = new CustomObject();

setTimeout(customObj.alert, 1000); // the alert message says `undefined`
setTimeout(function() {
    customObj.alert();
}, 2000); // the alert message says "Hello world from my custom object"
Run Code Online (Sandbox Code Playgroud)

在匿名函数中包装函数也是在JavaScript中使用闭包的关键:

var arr = ['a','b','c','d','e'];

// will always alert undefined
for(var i=0; i<arr.length; i++) {
    setTimeout(function() {
        console.log(arr[i]);
    }, 1000*i);
}

// outputs the values of `arr`
for(var j=0; j<arr.length; j++) {
    setTimeout((function(indx) {
        return function() {
            console.log(arr[indx]);
        }
    }(j)), 1000*j);
}
Run Code Online (Sandbox Code Playgroud)


Ray*_*hen 5

如果您需要具有单独的标识,则环绕非常有用.

var x = function () { cleanup(); };
var y = function () { cleanup(); };
if (x === y) ... // not true
Run Code Online (Sandbox Code Playgroud)

例如,某些功能如addEventListener操作身份.

element.addEventListener("myEvent", beep, false);
element.addEventListener("myEvent", beep, false);
Run Code Online (Sandbox Code Playgroud)

你第二次打电话addEventListener,它说:"我已经有了一个beep;我不需要添加另一个." 当myEvent事件被触发时,您只会发出一声嘟嘟声.如果您想要发出两声嘟嘟声,则需要确保回调不同.

element.addEventListener("myEvent", function() { beep(); }, false);
element.addEventListener("myEvent", function() { beep(); }, false);
Run Code Online (Sandbox Code Playgroud)

每个匿名函数都不同,所以这次你注册了两个函数(碰巧做同样的事情).现在它会发出两声哔哔声.