错了'这'扩展Map中的引用

Wrong 'this' reference in extending Map

本文关键字:引用 错了 扩展 Map      更新时间:2023-09-26

我正试图在Map<K, V>接口上编写一个简单的方法。到目前为止,我所做的是:MapExtensions.ts:

interface Map<K, V> {
    clone(): Map<K, V>;
}
Map.prototype.clone = () => {
    var self = this;
    console.log(self);
    let retval = new Map();        
    self.forEach((value, key) => {
        retval.set(key, value);
    });
    //for (let [key, value] of self.entries()) {
    //    retval.set(key, value);
    //}
    return retval;
};

然而,在测试该方法时,我最终发现this参数中的引用错误地引用了Window对象,因此,self.forEach不起作用,在测试时它说self.forEach is not a function(与self.entries()相同)。这是我的测试脚本:

test("clone test", () => {
    //Arrange
    const source = new Map().set(1, "abc").set(2, "def").set(3, "ghi");
    //Act
    const actual = source.clone.bind(source)();//This fails.
    //const actual = source.clone();//This too fails.
    //Assert
    console.log(actual);
    console.log(expected);
    deepEqual(actual, source, "Cloned correctly");
});

附加信息:

  1. 以下是生成的JavaScript输出:

    var _this = this;//It seems this is causing the problem.
    Map.prototype.clone = function () {
        var self = _this;
        var retval = new Map();
        console.log(self);
        self.forEach(function (value, key) {
            retval.set(key, value);
        });
        return retval;
    };
    
  2. 我使用的是Visual Studio 2015,以及typescript中的默认JavaScript输出生成器。

如何成功做到这一点?

这是因为您使用的是箭头函数。当您需要访问this时,不要使用箭头函数。

Map.prototype.clone = function() { ... }