4

假设我在 JavaScript 中有两个函数,我想将this指针从一个传递到另一个。我知道有两种方法可以做到这一点(如下所示)。哪一个是最佳实践?

选项1:

function a() {
    b(this);
}

function b(elem) {
    alert(elem);
}

选项 2:

function a() {
    b.call(this);
}

function b() {
    alert(this);
}
4

3 回答 3

7

这并没有回答问题,而是更改之前问题的标题:
JavaScript 中的 function.call(this) 和 function(this) 有什么区别?


使用设置被调用函数call的上下文( ):this

function foo() {
    console.log(this);
}  

foo(); // window
foo.call({}); // {}

上面的示例显示了使用非严格模式(在浏览器环境中)的默认上下文window

非严格模式是默认模式。仅部分浏览器支持严格模式。

如果函数是对象的方法,则上下文就是对象本身:

var obj = {
    foo: function () {
        console.log(this);
    }
};

obj.foo(); // obj
obj.foo.call({}); // {}

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this

于 2013-04-11T20:19:22.630 回答
2

一般来说,实际上没有最佳实践,只有指导方针。这完全取决于您编码的方式。就个人而言,我会使用第一种形式,它更面向功能而不是面向对象,并且您避免了额外的操作——更改上下文对象——另外,你不会依赖于上下文对象本身。这意味着,如果您需要在b某个地方重用,您没有时间来更改它的上下文对象。

我会给你一个实际的例子。假设这b是一个将 的 设置为的style.display函数。让我们称之为:elementnonehide

function hide(element) {
    element.style.display = "none";
}

你可以像这样使用它:

hide(document.getElementById("foo"))

到目前为止,一切都很好。但是如果你想隐藏列表的所有元素呢?

// this is used to have an array of element for the example,
// because NodeList are not Array
var slice = Function.call.bind(Array.prototype.slice);
var nodes = slice(document.getElementsByTagName("div"));

nodes.forEach(hide);

你简单得过hide。那是因为您传递给的回调forEach称为将数组的每个值作为第一个参数传递。

但这还没有结束。假设您不想隐藏列表中的所有 div,而只想隐藏列表中包含文本“foo”的 div。

function hasFoo(element) {
    return element.textContent.indexOf("foo") > -1
}

然后:

nodes.filter(hasFoo).forEach(hide);

等等。如果您决定将函数的“主题”作为第一个参数传递,您可以真正利用 JavaScript 的函数式编程方面和方法。

在这里你可以找到 ES5 方法的文档,比如filterforEach

于 2013-04-11T20:42:54.217 回答
1

我知道有两种方法可以做到这一点(如下所示)。

如您所见,两者都有效:-)

哪一个是最佳实践?

这取决于。哪个更适合您的代码结构?

如果您正在编写非常面向对象的代码,并且两个函数都编写在一个社区中,您希望所有内容都是一个方法和this关键字,以在任何地方引用一个对象实例,那么您不应该破坏它。

如果没有,为简单起见,您应该选择选项#1。此外,您可能需要考虑其他形式参数b- 如果对象引用与它们不一致,选项 #2 可能会更好。

于 2013-04-11T20:23:41.870 回答