在 JavaScript 中,“this”是当函数位于对象的对象内时似乎会迷失方向

发布于 2024-11-27 09:25:14 字数 907 浏览 1 评论 0原文

对象 F 有一个存储为 this.fnthis.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); };

这似乎暗示 F.state.fn 中的 this 上下文是不是 F 而是 F.state - 对我来说完全违反直觉——这是对的吗!?

the object F has a function stored as this.fn and this.state.fn. can be called successfully as f.fn() but not as 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!

the problem seems to be that the function is stored in the object state, because this works:

f1.state.fn.call( f1 );
F.prototype.fn = function() { this.state.fn.call(this); };

which seems to imply that the this context within F.state.fn is not F but rather F.state - which to me is completely counter-intuitive - is this right!?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

累赘 2024-12-04 09:25:14

在函数内,this 完全取决于您如何调用该函数。

当您使用对象中的点表示法调用函数时,this 将自动设置为该对象。

如果你说 someObject.someChildObject.someFunction() 那么在 someFunction() 中你会发现 this 将被设置为 someChildObject< /代码>。

因此,在您的示例中, f1.fn() 应该导致 thisfn() 内的 f1,但随后在该函数中,您输入 this.state.fn() - 它将使用 thisstatefn() code> 设置为 state

您可以使用callapply> 覆盖此行为。

另一个供您感兴趣的示例:

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 该函数将记录该属性。

Within a function, this depends entirely on how you called the function.

When you call a function using dot notation from an object this will be automatically set to that object.

If you say someObject.someChildObject.someFunction() then within someFunction() you'll find this will be set to someChildObject.

So in your example f1.fn() should result in this being f1 within fn(), but then within that function you say this.state.fn() - which will call state's fn() with this set to state.

You can override this behaviour using call or apply.

Another example just for your interest:

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'

If you create a reference to a function originally defined as an object property and call the function via that reference then this will be whatever applies to your new reference. In my example the x reference is a global, which in practice means it belongs to the window object. What you can learn from this is that the function that f1.f() calls doesn't really belong to f1 at all.

Continuing that example:

f2 = {};
f2.i = "hello";
f2.f = f1.f;
f2.f(); // 'this' will be f2, so should log "hello"

When you call f2.f(), you'll find this is set to f2, and because I've set a property f2.i the function will log that property.

不疑不惑不回忆 2024-12-04 09:25:14

实例

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.istate.i 在我的情况下是 42 但在你的情况下是 undefined

您也可以通过执行 .bind 来强制 this 不是 state 而是您期望的对象

this.state = {
    'fn': f.bind(this)
};

,但是 ES5 中您应该这样做获取 ES5 垫片

Live example

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!

When you call state.fn() it prints this.i which is state.i which is 42 in my case but undefined in your case.

You can alternatively force this to not be state but to be the object you expect it to be by doing

this.state = {
    'fn': f.bind(this)
};

.bind is ES5 however so you should get the ES5-shim

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文