首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当仅显式绑定似乎保证回调的这个上下文不能被覆盖时,硬绑定的目的是什么?

当仅显式绑定似乎保证回调的这个上下文不能被覆盖时,硬绑定的目的是什么?
EN

Stack Overflow用户
提问于 2021-06-24 07:52:46
回答 1查看 97关注 0票数 0

我跟随凯尔辛普森的YDKJS系列书,有一个关于显式还是硬装订的问题。凯尔解释说,仅靠显式绑定并不一定足以保证我们传递回调的函数将保留回调的this上下文。他列举了一些例子,在这些情况下,库/框架中的函数有时会恼怒地强制this在回调中引用什么--传递给与显式设置它相同的东西。因此,我试着测试这看起来可能是什么样子,并假设以下代码的行为会有所不同:

代码语言:javascript
运行
复制
function foo() {
    console.log(this.a);
}
var obj = {
    a: 5
}
var obj2 = {
    a: 10
}
function bar(f) {
    f.call(obj2); // 5 --> expected explicit binding to be overwritten here, but this doesn't happen (expected 10 and got 5)
}
bar(foo.bind(obj)); // explicit binding made here

我认为这将成功地覆盖this所指的内容(这就是我们需要硬绑定的原因)。首先,下面是使用硬绑定的相应示例。

代码语言:javascript
运行
复制
    function foo() {
        console.log(this.a);
    }
    var obj = {
        a: 5
    }
    var obj2 = {
        a: 10
    }
    // hard binding here
    function baz() {
        foo.call(obj);
    }
    function bar(f) {
        f.call(obj2); // 5 --> Here, it makes sense that we would get 5
    }
    bar(baz);

让我解释一下我认为硬约束的目的是:

我认为bar可以覆盖回调的this上下文。事实上,凯尔·辛普森本人认为这是可能的,也是最初难以约束的原因。硬绑定解决了这个显然存在的问题,因为即使bar强制更改回调baz的this上下文,更改baz的this引用实际上并不会起到任何作用,因为它不会影响thisfoo.call(obj)中所指的内容,而且bar不能改变这一点。

但是,我正在尝试复制显式绑定失败的场景,但似乎不能这样做。我不能覆盖函数的this上下文,即使它不是硬绑定和显式绑定。有什么想法会让我误入歧途吗?

编辑:当我不将函数作为回调传递时,在全局范围内,我可以执行foo.call(obj)和获取5,然后执行foo.call(obj2)和get 10,但这不是覆盖吗?这些只是具有不同绑定的foo调用的两个不同实例。

EN

回答 1

Stack Overflow用户

发布于 2021-06-24 09:08:22

在阅读了注释之后,我做了一些研究和测试,试图打破bind方法,发现当使用new运算符调用绑定函数时,将忽略预先赋值的this值,并保留预先赋值的参数。

因此,绝对有一种方法可以更改函数的以前绑定的this (参见下面的脚本),操作“硬绑定”示例可以避免这种情况!

我必须指出,我也尝试了其他丑陋的东西,如eval,但没有成功。

无论如何,说到库,处理用户定义的函数(或回调)上下文对我来说似乎是一种糟糕的做法。做下面的事太疯狂了,我不认为有人会这么做。然而,为了知识而知道这一点是很好的。

代码语言:javascript
运行
复制
const a = {value: 1};
const b = {value: 2};

const fn = function() {console.log(this.value);};

const boundA = fn.bind(a);
const hardBoundA = function() {fn.call(a);};

const reBoundB = (new boundA()).constructor.bind(b);
const hardReBoundB = (new hardBoundA()).constructor.bind(b);

boundA();
hardBoundA();

reBoundB()
hardReBoundB();

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68111664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档