修改数组.forEach自动将上下文设置为调用者
Modifying Array.forEach to Automatically Set the Context to be the Caller
是否可以创建Array的替代品?forEach自动将上下文"this"设置为与调用方法时相同的上下文?
例如(不工作,不知道为什么):
Array.prototype.each = function(fn) {
return this.forEach(fn, arguments.callee.caller);
}
function myFunction() {
this.myVar = 'myVar';
[1,2,3].each(function() {
console.log(this.myVar); // logs 'myVar'
});
}
数组。forEach已经接受了一个上下文参数作为可选的最后一个参数
(function() {
this.myvar = "myvar";
[1,2,3,4].forEach(function(v) {
console.log("v:"+v);
console.log("myvar="+this.myvar);
}, this);
})();
参见MDN forEach
同样,上面的例子(如果我们不处理关于this
的实例上的方法)在不使用bind
或forEach
的可选上下文参数的情况下也可以工作,以下内容也可以正常工作:
function myFunction() {
this.myVar = 'myVar';
[1,2,3].forEach(function() {
console.log(this.myVar); // logs 'myVar'
});
}
myFunction();
因为javascript是函数作用域,所以匿名函数可以使用this
访问父函数的作用域,并正确记录日志。this
只有在处理实例方法时才真正成为问题。
答案是否定的,JavaScript函数不能确定调用者中的this
的值。
可以将传递的函数与当前对象绑定,如下所示
function myFunction() {
this.myVar = 'myVar';
[1,2,3].forEach(function() {
console.log(this.myVar); // logs 'myVar'
}.bind(this));
}
在ECMA Script 6中,您可以使用箭头函数,如下所示
[1,2,3].forEach(() => {
console.log(this.myVar); // logs 'myVar'
});
在传递回调函数时,另一种方法是将this
变量弄乱,您可以将this
赋值给一个新变量,以便子范围函数可以访问它:
Array.prototype.each = function(fn) {
return this.forEach(fn, arguments.callee.caller);
}
function myFunction() {
var me = this;
me.myVar = 'myVar';
[1,2,3].each(function() {
console.log(me.myVar); // logs 'myVar'
});
}
现在你不必记得传递this
作为第二个参数
首先,必须指出myFunction
是一个构造函数。但是,标识符中的第一个字母不是大写的。请称之为MyFunction
。
如果没有new
操作符调用构造函数,则this
绑定到全局对象,即浏览器中的window
。这使得大写约定成为我们发现此类错误的唯一方法。
// After the original code...
myFunction();
console.log(window.myVar); // logs "myVar"
其次,为了能够在任何数组上应用函数,而不是更改Array.prototype
,请考虑以下事项:
var utils = {array: {}}; // utils.array is a container for array utilities.
utils.array.each = function (array, func) {
var i;
for (i = 0; i < array.length; i += 1) { func(array[i]); }
};
utils.write = function (s) {
console.log(s); // Alternatively, document.write(s);
};
utils.array.each([1, 2, 3], utils.write); // prints 1 2 and 3 (on separate lines)
注意我们没有使用this
和new
。它们使JavaScript看起来像Java,除此之外,它们很少有什么有用的用途。
虽然库可以修改Object.prototype
和Array.prototype
,但最终开发人员不应该这样做。
同时,我们应该(理想情况下)能够这样做:
-
utils.array.each([1, 2, 3], console.log);
或 -
utils.array.each([1, 2, 3], document.write);
.
但是大多数浏览器不允许。
希望有帮助。
如果我正确理解您的需求,那么您正试图覆盖"this"。我想这对你有帮助。
- 如何设置EmberJS组件的上下文
- 关于设置超时/间隔上下文
- 为什么 context.restore() 不会将上下文的比例设置回 (1, 1)
- 如何在保留当前上下文的同时设置Timeout
- 如何设置javascript闭包的上下文
- JQuery widget:在子 widget 中设置上下文
- 上下文丢失.设置超时
- 为包定义的模板设置数据上下文
- Angular JS:如何为通过$http的所有调用设置上下文路径
- HTML5 画布:如何为上下文设置动画
- JavaScript 设置超时在 Android 上下文切换上
- TinyMCE onPaste 不设置内容,使用上下文菜单粘贴不会触发更改事件
- 如何设置html5画布's上下文属性
- 为所有查询设置jquery上下文
- Backbone.js,无法在回调上设置上下文
- 画布元素的宽度或高度更改后,其 2d 上下文的字体将设置为默认值
- 如何设置变量指向全局对象-独立于上下文执行
- 修改数组.forEach自动将上下文设置为调用者
- NetSuite -在我将上下文设置为'scheduled'之后,销售订单中的字段没有设置
- 将绑定上下文设置为属性