以下 Javascript 函数如何影响“this”的值

How do the following Javascript functions affect the value of 'this'?

本文关键字:this 的值 影响 函数 Javascript 何影响 以下      更新时间:2023-09-26

我有一个对象,里面有两个函数,正如我猜的那样,每个函数都有不同的this值:

custom_controls : {
    play_pause : function () {
        console.log(this); // object
        videoPlayer.getIsPlaying(function (video_is_playing) {
            if (video_is_playing) {
                console.log(this); // window
                videoPlayer.pause(true);
            } else {
                videoPlayer.play();
            }
        });
    }
},

然后像这样调用该函数:

custom_controls.play_pause()

我听说你调用函数的方式表示this的值。

所以我的问题是:这里发生了什么?我使用的是哪种类型的函数调用?每个如何影响this

调用obj.func()时,函数内部的this将等于obj。如果没有obj,则使用全局对象(window(。或者,如果您在严格模式下运行,则使用 undefined

第一个日志是你的对象,因为你像这样调用函数:

custom_controls.play_pause() // custom_controls will be 'this'

第二个日志是 window,因为作为参数传递给 getIsPlaying 的函数没有使用任何this调用:

videoPlayer.getIsPlaying = function(callback) {
  callback(); // this inside callback will be window
}

您可以使用 callapply 来控制调用函数时 this 的值。您可以使用 bind 函数创建一个新函数,该函数将始终将this值设置为您想要的任何值:

videoPlayer.getIsPlaying(function (video_is_playing) {
        if (video_is_playing) {
            console.log(this); // my obj
            videoPlayer.pause(true);
        } else {
            videoPlayer.play();
        }
    }.bind(this)); // magic!

参考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

每个函数实际上是在上下文中执行的。该上下文表示为为其调用函数的当前this

给定您的代码:如果你调用custom_controls.play_pause()你说的是"获取名为play_pause的对象custom_controls字段并在对象custom_controls的上下文中执行它"。

后来打电话给videoPlayer.getIsPlaying()的意思几乎是一样的。除非你给它一个回调函数。稍后如何执行该回调函数取决于videoPlayer.getIsPlaying的实现方式。如果我必须猜测,我会说getIsPlaying在某处有一个callback.call(window, video_is_playing)

call是javascript中所有函数对象的方法。

如果您想在某些回调中引用this,有几种方法可以解决此"问题"。

var self = this;
call_me_maybe(function() {
    console.log(this); //the this that call_me_maybe chose to call your function with
    console.log(self); //the this from the upper scope
});

或者,如果您不关心call_me_maybe将在上下文中调用函数的对象:

call_me_maybe((function(){
    console.log(this); //the this from the upper scope
}).bind(this));

bind所做的是它返回一个 wrap[per 函数,该函数将始终在绑定到的对象的上下文中调用。 bind还可以绑定函数的参数以及this对象,从而创建一种咖喱。

你的第一个指的是play_pause

您的第二个这可能是指窗口或您的视频播放器对象。在 JavaScript 中,闭包和正则函数"通常"附加到window,调用 this 返回window。在某些情况下,例如,如果您将函数附加到 HTML 元素的点击处理程序,是指该元素......

element.onclick = function(){
  this // -> element
}

但一般来说,如果你只是创建一个function(),或者有一个像你这样的匿名this指的是window

function hello(){
  this // -> window
}

您发现的this是对象是您所期望的,因为函数正在该对象上运行。

我不熟悉您的videoPlayer,但由于this的值是"窗口",我会想象 A 视频播放器是浏览器本身的功能,或者 B 它的范围没有正确关闭。

this是指函数的"专有",或者来自函数的对象是方法。

定义基本函数时,"专有"是页面(或窗口(本身。

您可以查看callback文档以了解解决方法

当你调用videoPlayer.getIsPlaying时,它接受一个回调fn。 回调像cb()一样直接调用,因此上下文是全局的(窗口(。

实现在对象上下文中发生的回调。您可以使用

var fn = cb.bind(customControl);
videoPlayer.getIsPlaying(fn);    

根据经验,当调用函数时,object.function将其设置为 object .如果直接调用函数,则this设置为 window。 Function.bind绑定object(此值(后返回函数(可选(以及参数。

阅读:MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind