在javascript中需要帮助包装函数并正确处理“this”

In javascript need help wrapping a function and handling "this" properly

本文关键字:正确处理 this 函数 包装 javascript 帮助      更新时间:2023-09-26

我开始尝试创建一个计时器函数,该函数可以让我包装一个回调函数,以便以后可以动态更改行为。

这导致我普遍意识到我真的还不了解函数,并且绝对不了解"这个"发生了什么

我在 jsfiddle 上设置了一个测试环境

myns = {};
myns.somefunc = function(txt) {
    this.data = txt;
    this.play = function() {
        alert(this.data + ' : '+dafunc.data);
    };
};
var dafunc = new myns.somefunc('hello world');
myns.Timer = function(msec, callback) {
    this.callback = null;
    this.timerID = null;
    this.ding = function() {
        this.callback();
    };
    this.set1 = function( msec, callback ) {
        this.stop();
        this.callback = callback;
        this.timerID = setTimeout(this.ding, msec );
    };
    this.set2 = function( msec, callback ) {
        this.callback = callback;
        var wrappedDing = (function(who) {
            return function() {
                who.ding();
            };
        })(this);
        this.timerID = setTimeout(wrappedDing, msec );
    };
    //this.set1(msec, callback);
    this.set2(msec, callback);    
};
var ttimer = new myns.Timer(1000, dafunc.play);

如果我使用 set1 方法,那么回调不起作用。所以我正在尝试 set2 方法。这让我想到了播放方法,但"这个"并不是指某个func的实例。

以为我走在正确的轨道上,但"这个"的混淆让我感到困惑。

欢迎任何线索。

问题是,与像python这样的语言不同,当你拿一个dafunc.play并将其传递给其他地方(回调= dafunc.play(时,它忘记了它与dafunc相关联,儿子,你需要使用另一个包装函数,就像你在set2函数中所做的那样。

var ttimer = new myns.Timer(1000, function(){ return dafunc.play(); });

自己制作所有额外的功能很烦人。您可以改用较新浏览器中可用的 bind 方法:

var wrappedDing = this.ding.bind(this);
new myns.Timer(1000, dafunc.play.bind(dafunc) );

或者,如果您也需要支持旧版本的 IE,则可以使用类似的填充程序。


最后,如果您不打算利用某种形式的继承或动态绑定,则可以重写代码以使用闭包。由于所有内容都是按字典划分的,因此您不必再担心this

(顺便说一句,我最终简化了过程中的代码...

myns = {};
myns.somefunc = function(txt) {
    var obj = { data : txt };
    obj.play = function() {
        alert(obj.data);
    };
    return obj;
};
var dafunc = myns.somefunc('hello world');
myns.timer = function(msec, callback) {
    var timerID = null;
    var set = function(){
        stop();
        timerID = setTimeout(callback, msec);
    };
    set();
    return { 
         set: set
    };
};
var ttimer = myns.timer(1000, dafunc.play);

最后一件事:如果您不讨厌自己,请使用控制台.log以及浏览器的调试器和开发控制台,而不是使用警报进行输出。