我有一个构造函数,它注册一个事件处理程序:
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', function () {
alert(this.data);
});
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor('foo', transport);Run Code Online (Sandbox Code Playgroud)
但是,我无法data在回调中访问已创建对象的属性.它看起来this并不是指创建的对象,而是指另一个对象.
我还尝试使用对象方法而不是匿名函数:
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', this.alert);
}
MyConstructor.prototype.alert = function() {
alert(this.name);
};
Run Code Online (Sandbox Code Playgroud)
但它表现出同样的问题.
如何访问正确的对象?
我注意到,似乎没有明确解释this关键字是什么以及如何在Stack Overflow站点上的JavaScript中正确(和错误地)使用它.
我亲眼目睹了一些非常奇怪的行为,并且无法理解为什么会发生这种行为.
this工作如何以及何时使用?
我已经看到"this"关键字如何在函数中起作用?,但我不认为它回答了以下问题.
鉴于此代码:
var MyDate = function(date) {
this.date = date;
};
var obj1 = {
foo: new Date(),
bar: new MyDate(this.foo) // this.foo is undefined
};
var obj2 = {};
obj2.foo = new Date();
obj2.bar = new MyDate(this.foo); // this.foo is undefined
var obj3 = {
foo: new Date(),
bar: new MyDate(obj3.foo)
};
var obj4 = {};
obj4.foo = new Date();
obj4.bar = new MyDate(obj4.foo);
Run Code Online (Sandbox Code Playgroud)
为什么前两次尝试失败,但最后两次失败?如果this没有绑定到当前对象的文字,什么是它必然?
我喜欢ES6类但我无法理解为什么我必须在这样的构造函数中绑定方法:
constructor() {
this.someMethod = this.someMethod.bind(this)
}
Run Code Online (Sandbox Code Playgroud)
对于任何方法我都需要这样做.
这是一个真正的限制还是我错过了什么?这背后的原因是什么?我知道JS中的类只是语法糖,但这可能是它们的一部分.
我正在玩不同的方法来调用一个函数,这个函数是Javascript中Object的一个属性,并查看哪个类型的调用将'this'设置为Object,并将'this'设置为Global Object.
这是我的测试代码:
var foo = {
bar: function(){
console.log('this:' + this);
}
}
console.log('calling foo.bar()');
foo.bar();
console.log('\ncalling (foo.bar)()');
(foo.bar)();
console.log('\ncalling f=foo; f.bar()');
f = foo; f.bar();
console.log('\ncalling f=foo.bar; f()');
f = foo.bar; f();
console.log('\ncalling (f=foo.bar)()');
(f = foo.bar)();
Run Code Online (Sandbox Code Playgroud)
这就是结果:
calling foo.bar()
this:[object Object]
calling (foo.bar)()
this:[object Object]
calling f=foo; f.bar()
this:[object Object]
calling f=foo.bar; f()
this:[object global]
calling (f=foo.bar)()
this:[object global]
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么f=foo.bar; f();并将(f=foo.bar)();'this'指定为全局对象
假设,为了这个问题,我希望能够在Javascript中创建一个函数,将一个数组的所有元素追加到另一个数组.实现此目的的一种方法是,如果您有权访问目标数组,则说:
var destination = [1,2,3];
var source = [4,5];
Array.prototype.push.apply(destination, source);
console.log(destination); // [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)
现在,由于Array.prototype.push.apply非常丑陋,我想将它别名为更好的东西,例如:
var pushAll = Array.prototype.push.apply;
Run Code Online (Sandbox Code Playgroud)
我应该能够使用两个参数调用,上下文(目标)和参数数组(源).但是,当我尝试使用别名时,会发生以下情况:
pushAll(destination, [6,7]);
TypeError: Function.prototype.apply was called on [object global], which
is a object and not a function
Run Code Online (Sandbox Code Playgroud)
所以很明显这个apply函数没有绑定push,这让我尝试了这个:
var pushAll = Function.prototype.apply.bind(Array.prototype.push);
pushAll(destination, [6,7]);
console.log(destination); // [1,2,3,4,5,6,7,8]
Run Code Online (Sandbox Code Playgroud)
这显然很好.我的问题是,为什么我必须绑定push方法才能应用?不应该绑定Array.prototype.push.apply吗?为什么以不同的名称调用它会导致在未绑定的上下文中调用它?
为什么在javascript中如果将对象方法引用到某个变量,则会丢失该对象上下文.无法找到任何链接,解释引擎盖下发生的事情.除了这个说明: 'this'指的是'拥有'不接缝为真的方法的对象.
var Class = function() {
this.property = 1
}
Class.prototype.method = function() {
return this.property;
}
var obj = new Class();
console.log(obj.method() === 1);
var refToMethod = obj.method; // why refToMethod 'this' is window
console.log(refToMethod() !== 1) // why this is true?
var property = 1;
console.log(refToMethod() === 1)
Run Code Online (Sandbox Code Playgroud) javascript ×7
this ×3
apply ×1
bind ×1
callback ×1
class ×1
ecmascript-6 ×1
methods ×1
oop ×1
prototype ×1