gpt4 book ai didi

javascript - 将回调作为值传递和作为扩展箭头函数传递之间的区别

转载 作者:行者123 更新时间:2023-12-04 09:06:23 25 4
gpt4 key购买 nike

传递回调时,按值执行:

utility.subscribe(this.callback);
与将其作为扩展形式传递不同吗?
utility.subscribe(arg => this.callback(arg));
我理解它们是等效的,但是当需要将上下文与回调一起传递时遇到了问题。

var utility = {
name: 'utility',
subscribe(callback) {
var msgForCallback = 'Hey callback!';
callback(msgForCallback);
}
}

var user = {
name: 'user',
useSubscriber() {
utility.subscribe(
this.callback
);
},
useSubscriberWithArrow() {
utility.subscribe(
arg => this.callback(arg)
);
},
callback (arg) {
console.log(`Context: ${this.name}`);
console.log(`The utility says: ${arg}`);
}
}

console.log('\nCall user.useSubscriber();');
user.useSubscriber();
console.log('\nCall user.useSubscriberWithArrow();');
user.useSubscriberWithArrow();

我意识到回调函数是一个常规函数,这就是上下文可能丢失的原因。所以我尝试将其更改为箭头函数,但即使是带有扩展回调的调用也会丢失上下文。
callback: (arg) => { .. }
代替
callback (arg) { .. }

var utility = {
name: 'utility',
subscribe(callback) {
var msgForCallback = 'Hey callback!';
callback(msgForCallback);
}
}

var user = {
name: 'user',
useSubscriber() {
utility.subscribe(
this.callback
);
},
useSubscriberWithArrow() {
utility.subscribe(
arg => this.callback(arg)
);
},
callback: (arg) => {
console.log(`Context: ${this.name}`);
console.log(`The utility says: ${arg}`);
}
}

console.log('\nCall user.useSubscriber();');
user.useSubscriber();
console.log('\nCall user.useSubscriberWithArrow();');
user.useSubscriberWithArrow();

最佳答案

  • 要了解您的代码有什么问题,您首先必须了解 regular function 之间的区别。声明和 arrow function宣言。 arrow function's this绑定(bind)到它的环境this (即定义的地方)。
  • 其次,你必须明白,在 object method 中的函数不指向 'this' of the object ,而是指向 global this即如下所示:
  • let obj = {
    someMethod() {
    function someFun() {
    // here 'this' points to 'global this'
    // i.e. 'this' does not points to obj
    }
    }
    }
    我想以上几点很清楚......
    现在,来到你的代码:
    第一次重写 callback作为 regular function .不要写成 arrow .
    我在下面的代码中提供了更多的行(用于调试目的):
    let utility = {
    name: 'utility',
    subscribe(callback) {
    let msgForCallback = 'Hey callback!';
    callback(msgForCallback);
    }
    };


    let user = {
    name: 'user',

    useSubscriber() {
    utility.subscribe(this.callback);
    },

    useSubscriberWithArrow() {
    utility.subscribe(arg => this.callback(arg + " With Arrow Huh "));
    },

    callback(arg) {
    console.log('this: ');
    console.log(this);
    console.log("-----------");
    console.log(`Context: ${this.name}`);
    console.log(`The utility says: ${arg}`);
    console.log("__________________________________________________________________________");
    }
    };


    console.log('\nCall user.useSubscriber();');
    user.useSubscriber();

    console.log('\nCall user.useSubscriberWithArrow();');
    user.useSubscriberWithArrow();
    我们将讨论上面给出的代码有什么问题。
    代码错误是 user.useSubscriber() 将无法解析 this.namecallback叫做。
    为什么?
    注: user.callback()不是 arrow函数,而是一个常规函数,并传递给 utility.subscribe() .所以,就像我上面描述的第二点一样, function with in object method ,所以, this将绑定(bind)到 global this .您可以通过运行代码来证明这一点。代码的输出有点像下面(我在 node v10.16.* 中测试过):
    Call user.useSubscriber();
    this:
    Object [global] {
    DTRACE_NET_SERVER_CONNECTION: [Function],
    DTRACE_NET_STREAM_END: [Function],
    DTRACE_HTTP_SERVER_REQUEST: [Function],
    DTRACE_HTTP_SERVER_RESPONSE: [Function],
    ...
    ...
    -----------
    Context: undefined
    The utility says: Hey callback!
    __________________________________________________________________________

    Call user.useSubscriberWithArrow();
    this:
    { name: 'user',
    useSubscriber: [Function: useSubscriber],
    useSubscriberWithArrow: [Function: useSubscriberWithArrow],
    callback: [Function: callback] }
    -----------
    Context: user
    The utility says: Hey callback! With Arrow Huh
    __________________________________________________________________________
    我想,这解决了问题。
    现在,为什么 user.useSubscriberWithArrow()作品 :
    它有效,请记住我在第一点中讨论过的内容 - arrow function is bind to it's environments 'this'(i.e. where it is defined) .所以,你通过了 arrow功能为 callback ,而不是 user.callback()本身,以及 arrow function用于调用 this.callback() .而且, arrow's this绑定(bind)到 user , 因为它是在 user 中定义的目的。
    我想这可以解决你的问题。如果您还有问题,请在评论中问我...

    关于javascript - 将回调作为值传递和作为扩展箭头函数传递之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63433566/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com