对象F的函数存储为this.fn
和this.state.fn
。可以f.fn()
成功调用,但不能f.state.fn()
function F( i, f ) { this.i = i; this.state = { 'fn':f }; this.f = f; }; F.prototype.inc = function() { this.i++ }; F.prototype.fn = function() { this.state.fn() }; f1 = new F( 1, function() { console.log( this.i ); } ); f1.f(); // this works f1.inc(); // this works f1.state.fn; // prints the function f1.fn(); // undefined! f1.state.fn(); // undefined!
问题似乎是函数存储在对象state
中,因为这有效:
f1.state.fn.call( f1 ); F.prototype.fn = function() { this.state.fn.call(this); };
这似乎暗示this
中的F.state.fn
上下文不 F
,而是F.state
- 这对我来说完全是反...直觉 - 这是对的!?
答案 0 :(得分:1)
function F(i, f) {
this.i = i;
this.state = {
'fn': f,
i: 42
};
this.f = f;
};
F.prototype.inc = function() {
this.i++
};
F.prototype.fn = function() {
this.state.fn()
};
f1 = new F(1, function() {
console.log(this.i);
});
f1.f(); // this works
f1.inc(); // this works
f1.state.fn; // prints the function
f1.fn(); // 42!
f1.state.fn(); // 42!
当您致电state.fn()
时,会打印this.i
,state.i
在我的情况下为42
,但在您的情况下为undefined
。
您也可以强制this
不是state
,而是成为您期望的对象
this.state = {
'fn': f.bind(this)
};
.bind
是ES5但是你应该得到ES5-shim
答案 1 :(得分:1)
在一个函数中,this
完全取决于你如何调用函数。
使用来自对象this
的点表示法调用函数时,将自动设置为该对象。
如果你说someObject.someChildObject.someFunction()
然后在someFunction()
内,你会发现this
将被设置为someChildObject
。
因此,在您的示例f1.fn()
中,this
应该f1
fn()
this.state.fn()
,但是在该函数中你会说state
- 这会调用{ {1}} fn()
this
设置为state
。
您可以使用call
或apply
覆盖此行为。
另一个仅为您感兴趣的例子:
function F( i, f ) {
this.i = i;
this.state = { 'fn':f };
this.f = f;
};
f1 = new F( 1, function() { console.log( this.i ); } );
f1.f(); // works - 'this' will be f1
var x = f1.f; // create a reference to the same function
x(); // won't work - 'this' will probably be 'window'
如果您创建对最初定义为对象属性的函数的引用并通过该引用调用该函数,那么this
将适用于您的新引用。在我的示例中,x
引用是全局的,实际上它意味着它属于window
对象。您可以从中学到的是f1.f()
调用的函数根本不属于f1
。
继续这个例子:
f2 = {};
f2.i = "hello";
f2.f = f1.f;
f2.f(); // 'this' will be f2, so should log "hello"
当您致电f2.f()
时,您会发现this
设置为f2
,并且因为我设置了属性f2.i
,该功能将记录该属性。