为什么& # 39;这个# 39;指'window'而不是类实例

Why 'this' refers to 'window' instead of a class instance

本文关键字:实例 这个 为什么 window      更新时间:2023-09-26

我有一个包装器函数,我得到全局对象( root = this ),然后我启用严格模式并声明一些函数。

在这个包装器函数中,我有一个类,我正确地调用它(使用 new 操作符)。问题是在我的原型方法中访问该类的实例,因为它引用全局对象,使用 this

这是我正在写的代码,我删除了一些不相关的部分,以推动自己的问题。

注意:exports.Timer是使用_timer的类。

(function(root, name, factory) {
    'use strict'
    factory(typeof root['exports'] === 'object' ? module.exports : root[name] = {})
})(this, 'timerEx', function(exports) {
    var root = this
    'use strict'
    /* my class */
    function _timer(id, options) {
        this.anim = options.anim
        this.delay = options.delay
        this.exec = typeof (this.fnc = options.callback) === 'function'
        this.id = id
    }
    _timer.prototype = {
        'start': function() {
            // here's the problem.
            // this is equal to 'window'
            console.log(this instanceof _timer) // false
            this.state = true
            if (this.isAnim = (this.anim && typeof requestAnimFrame === 'function')) {
                this._then = receiveTime()
                animRun(this)
            } else timeoutRun(this)
        },
        'stop': function() {
            if (this.state)
                    (this.isAnim ? cancelAnimFrame : clearTimeout)(this.xId)
            this.isAnim = null
            this.state = false
        }
    }
    var timers = []
    function getReservedTimerId() {
        var len = timers.length - 1
        if (len <= 0) return 0;
        for (var i = 0, reserved; i <= len; ++i) {
            if (i === len)
                reserved = i + 1
            else if ((timers[i].id + 1) < timers[i + 1].id) {
                reserved = timers[i].id + 1
                break
            }
        }
        return reserved
    }
    function getTimerById(id) {
        var timer
        for (var i = 0, len = timers.length; i < len; ++i) {
            if (timers[i].id === id) {
                timer = timers[i]
                break
            }
        }
        return timer
    }
    exports.Timer = function(options) {
        typeof options !== 'object' && (options = {})
        for (var i in def_options)
            typeof options[i] !== typeof def_options[i] && (options[i] = def_options[i])
        var id = getReservedTimerId()
        timers.push(new _timer(id, options))
        this.__id__ = id
    }
    exports.Timer.fn = exports.Timer.prototype = {
        'delay': function(rate) {
            getTimerById(this.__id__).delay = rate
        },
        'toggle': function(state) {
            var timer = getTimerById(this.__id__)
            timer[(typeof state === 'boolean' ? state : timer.state) ? 'stop' : 'start']()
        }
    }
})

当你这样做的时候:

(state ? timer.start : timer.stop)()

然后是表达式计时器。Start 返回一个函数,然后在没有基对象的情况下调用该函数,因此它的this在调用中未定义,因此在函数中,它默认为全局对象。它相当于:

var a = timer.start;
a();

function Foo(){};
Foo.prototype.start = function(){
  return this instanceof Foo;
}
var a = new Foo();
console.log('Normal call: ' + a.start());
console.log('Conditional call: ' + (true? a.start : null)());