函数包装器在javascript中的重要性

dan*_*ods 2 javascript function

有人可以向我解释使用函数包装器的重要性(即:在分配onclick功能时)吗?我知道我应该,但我不完全理解为什么......

示例:我的理解是:

$(callingImg)[0].setAttribute("onclick", "function(){removeChildren(this);}");
Run Code Online (Sandbox Code Playgroud)

比这更好:

$(callingImg)[0].setAttribute("onclick", "removeChildren(this)");
Run Code Online (Sandbox Code Playgroud)

Jus*_*son 12

函数包装器最常见的用途之一是维护或锁定该函数的上下文.例如,如果你有一些对象,并且你想使用它的一个方法作为onclick给定元素的处理程序:

someElement.onclick = someObject.someMethod;
Run Code Online (Sandbox Code Playgroud)

如果someObject.someMethod进行任何引用this,而不是this指向someObject它将指向,someElement因为上下文已更改.通过包装someObject.someMethod

someElement.onclick = function() { someObject.someMethod() };
Run Code Online (Sandbox Code Playgroud)

你仍然someMethod作为一种方法someObject而不是作为一种方法来执行someElement.

但是,如果事件处理程序方法从不进行任何引用this,则不需要包装器.

从您发布的示例代码中,如果您刚刚执行了此操作

$(callingImg)[0].setAttribute("onclick", removeChildren(this));
Run Code Online (Sandbox Code Playgroud)

removeChildren(this)将立即执行,它的返回值将被指定为onclick处理程序.


这里有一些示例代码来说明正在发生的事情

var FakeElement = function() {
    this.name    = "FakeElement";
    this.onclick = function() {};
};

var FakeEventHandler = function() {
    this.name = "FakeHandlerObject";
    this.clickHandler = function() {
        console.log("`this` = ", this.name);
    };
};

var e = new FakeElement(); 
var h = new FakeEventHandler();

// Normal usage, `this` points to instance of `h`
console.info("h.clickHandler();");
h.clickHandler();

// Context of this is changed to `e` instead of `h`
console.info("e.onclick = h.clickHandler;");
e.onclick = h.clickHandler;
e.onclick();

// Wrapped to maintain proper context of `this` within `h`
console.info("e.onclick = function() { h.clickHandler(); };");
e.onclick = function() { h.clickHandler(); };
e.onclick();

// Executed immediately and returns `null` causing an error in `e.onclick();`
console.info("e.onclick = h.clickHandler();");
e.onclick = h.clickHandler();
e.onclick();
Run Code Online (Sandbox Code Playgroud)

输出:

h.clickHandler();
`this` = FakeHandlerObject

e.onclick = h.clickHandler;
`this` = FakeElement

e.onclick = function() { h.clickHandler(); };
`this` = FakeHandlerObject

e.onclick = h.clickHandler();
`this` = FakeHandlerObject
Run Code Online (Sandbox Code Playgroud)

作为旁注,看起来你正在使用jQuery.如果是这样的话,你可以干脆做

$($(callingImg)[0]).click(function() {
    removeChildren(this);
});
Run Code Online (Sandbox Code Playgroud)

更好的是,如果总有一个,callingImg或者你想对每个应用相同的点击处理程序callingImg,你可以这样做

$(callingImg).click(function() {
    removeChildren(this);
});
Run Code Online (Sandbox Code Playgroud)