为什么定义属性中的“this”范围错误?

时间:2016-12-21 23:43:46

标签: javascript function prototype

我在我的代码中创建了一个debounce函数,我做了一个非常简单的例子,但是当它与Object.defineProperty结合使用时,“this”的值是值得怀疑的。

这是代码:

// Debounce a function call
Object.defineProperty(Function.prototype, "debounce", {
    enumerable: false,
    writable: false,
    value: function(ms, scope) {
        var fn = this,
            time = ms,
            timer;
        function debounced() {
            var args = arguments;
            if (timer) clearTimeout(timer);
            timer = setTimeout(function() { fn.apply(scope, args); }, time);
        }
        return debounced;
    }
});

它被调用(其中.bind ...作为外部库的一部分完成):

function() {
    console.log(this.something);
}.debounce(300).bind(someObject)();

它有效,但不能使用“this”的值。在值函数中,“this”指向原始函数。无论如何我可以通过这种设计风格获得约束范围吗?

实施例

var a = {
    b: function() {
        console.log(this.something);
    }.debounce(300),
};

var c = {
    something: true,
};

// I can't control this code -> 3rd party library
a.b.bind(c)();

1 个答案:

答案 0 :(得分:1)

在调用this时,您需要使用debounced debounced

在旧学校JS

Object.defineProperty(Function.prototype, "debounce", {
    value: function value(ms) {
        var fn = this,
            time = ms,
            timer;
        function debounced() {
            var _this = this;
            var args = arguments;
            if (timer) clearTimeout(timer);
            timer = setTimeout(function () {
                return fn.apply(_this, args);
            }, time);
        }
        return debounced;
    }
});

或更简单的ES2015 +

Object.defineProperty(Function.prototype, "debounce", {
    value: function(ms) {
        var fn = this,
            time = ms,
            timer;
        function debounced() {
            if (timer) clearTimeout(timer);
            timer = setTimeout(() => fn.apply(this, arguments), time);
        }
        return debounced;
    }
});

你也可以删除enumerable:false,writable:false,因为false是这些属性的默认值 - 使代码变小:p