当前位置: 首页 > 知识库问答 >
问题:

为什么bind()或apply()在这里不起作用,而call()起作用?

堵泽宇
2023-03-14

拿我正在试验的这个非常简单的框架来说(这样我就可以更深入地学习JavaScript的函数原型。)

(function(){
var app = {
    ui: {
        app: document.querySelector('.app'),
        settings: document.querySelector('.settings'),
    },
    actions: 'click settings openSidebar'
    ,
    functions: {
        openSidebar: function(e){
            console.log(this); // <- expected value of this is 'app.ui'
        }
    },
    run: function(){
        var a1 = this.actions.split("\n");
        var a2 = this.actions.split(" ");

        var self = this;
        this.ui[a2[1]].addEventListener(a2[0], function(e){
            app.functions.openSidebar.call(self.ui,e);
        });
    }
};
app.run();
})();

这工作很棒。控制台的输出是:

对象{ui:对象,操作:"单击设置openSidebar",函数:对象,运行:函数}

但是,当我尝试这样做时:

var self = this;
this.ui[a2[1]].addEventListener(a2[0], function(e){
    app.functions.openSidebar(e);
}.bind(this));

在openSidebar()中的this的上下文是openSidebar(又名bind没有效果)。控制台输出:

对象{openSidebar:function}

但是,当我尝试使用apply函数时,如下所示:

app.functions.openSidebar.apply(self.ui,e);

除了参数(e)没有通过之外,它工作正常(openSidebar中的这个app.ui),因此e==未定义的

下面是:

1.为什么在第一个示例中不绑定工作(根本不)?

2.为什么应用程序在不传递参数的情况下工作(e(事件))?

对于添加的布朗尼点数:

3.为什么电话会像预期的那样工作?

共有2个答案

茅才
2023-03-14

>

  • 你需要这样做:

    this.ui[a2[1]]. addEventListener(a2[0],app.functions.openSidebar.bind(this));

    Bind返回一个新函数,其中包含手动设置的传递内容。因为您没有在右边的函数上使用bind,所以您在调用函数的左边使用app.functions调用函数,从今以后在调用函数中称为this

    >

  • Apply将参数作为数组,而不是命名参数。。。

    我不能解释第三个,除非说电话就是这样工作的!

  • 酆勇
    2023-03-14

    在第一个示例中,为什么不绑定工作?

    它“有效”,只是没有达到你的期望。

    在anon函数中,这实际上是bind设置的值。但是,当您随后调用也是对象属性的函数(functions.openSidebar)时,对于该调用,此自动绑定到函数内部的该对象(即此===函数)。来自父上下文的this的值永远不会在调用链中“继承”。

    为什么应用程序在不传递参数的情况下工作(e(事件))?

    因为apply试图通过将调用作为数组来从它自己的第二个参数e中取出调用的参数。这意味着首先检查其length属性;您的事件对象没有长度,因此apply获取生成的undefined值,并有效地表现为在空数组中传递。有关详细信息,请参见带注释的ES5参考。

    为什么电话会像预期的那样工作?

    这是一个奇怪的问题。为什么它不起作用?你在使用它,就像它应该被使用一样。

     类似资料:
    • 问题内容: 我正在尝试通过以下方式将日期范围划分为各个日期: 而且我不知道为什么不起作用,因为日期仍然相同,所以循环变得无限。 问题答案: plusDays不会改变原始的,您必须分配结果:

    • 通过选择,,和,我创建了一个全新的Spring初始化项目。 我做了一个小项目: 我试着将三个人保存到数据库中。保存方法只返回需要执行的Mono。如果我尝试通过简单的订阅来执行它,一切都很好: 但是,当我使用而不是时,应用程序挂起: 如果我手动查询数据库,我会看到Jim已被保存,但Jack和John未被保存。 这是窃听器,还是我做错了什么?我希望在代码进一步发展之前保证用户在数据库中,所以我真的很想

    • 问题内容: 我正在尝试向div添加ajax响应(它是带有表,表单等的HTML代码)。 在FF中工作完美,但在IE中却给了我一个未知的错误。 我尝试了很多东西,但是只有当我添加jQuery并在要插入代码的div上运行该方法时,它才起作用。 有人在乎解释为什么这样做有效,而不是简单吗?我尝试查看代码,但我想我不是JS的佼佼者,因为我不了解它在做什么。 问题答案: IE 有 多个 文档(pre | ta

    • 所以我有了这个网格: 在中有一个没有空格的超长字符串。是具有固定尺寸的占位符。这就产生了上述结果: 但将更改为会得到以下结果: 它会溢出其父级和屏幕大小。为什么它的行为不像Minmax? 码本

    • 问题内容: 显然有一些根本尚不了解的东西。 我试图使用户成为Angular Ui.Bootstrap中的Modal模块的用户,但是我发现我的点击没有激活该功能- 因此将其简化为一个非常简单的测试用例,如下所示,当ng-click时我看不到任何调用指向一个函数(alert或console.log),但是当ng- click指向一个仅表示表达式的东西时确实起作用 为什么在第一个示例中未调用? http

    • 问题内容: 我正在尝试从JSON网址获取集合。骨干网确实发送了请求并得到了响应,但是在它之后的集合中没有: 这是我的JavaScript: 响应中的JSON 响应中的Content-Type HTTP标头为。 为什么不将其加载到集合中?JSON是否正确? 一些更多的代码: 问题答案: 是异步的。尝试 要么 要么