假设我在JavaScript中有两个函数,我想将this
指针从一个传递给另一个。我知道有两种方法可以做到这一点(如下所示)。哪一个是最好的做法?
选项1:
function a() {
b(this);
}
function b(elem) {
alert(elem);
}
选项2:
function a() {
b.call(this);
}
function b() {
alert(this);
}
答案 0 :(得分: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
答案 1 :(得分:2)
一般来说,实际上没有最佳实践,只是指导方针。这完全取决于你编码的方式。就个人而言,我会使用第一种形式,它更面向功能而不是面向对象,并且您避免了额外的操作 - 更改上下文对象 - 此外,您将不会依赖于上下文对象本身。这意味着,如果你需要在某个地方重用b
,你就没有时间来改变它的上下文对象。
我会给你一个实际的例子。假设b
是一个将style.display
的{{1}}设置为element
的函数。我们称之为none
:
hide
您可以像以下一样使用它:
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
的回调被称为传递数组的每个值作为第一个参数。
但还没有结束。假设你想要隐藏列表中不是所有div,而只隐藏列表中包含文本“foo”的div。
forEach
然后:
function hasFoo(element) {
return element.textContent.indexOf("foo") > -1
}
等等。如果您决定将函数的“主题”作为第一个参数传递,那么您可以真正利用JavaScript的函数式编程方面和方法。
答案 2 :(得分:1)
我知道两种方法(如下所示)。
如你所见,两者都有效: - )
哪一个是最佳做法?
这取决于。哪个更适合您的代码结构?
如果你的编码非常面向对象,并且两个函数都写在一个你希望一切都是方法的邻域中,并且this
关键字在任何地方引用一个对象实例,你就不应该打破它。 / p>
如果没有,您应该选择选项#1以简化。另外,您可能还需要考虑其他形式参数b
- 如果对象引用与它们不一致,则选项#2可能更好。