我有一个包装函数,我获取全局对象( 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']()
}
}
})
答案 0 :(得分:2)
当你这样做时:
(state ? timer.start : timer.stop)()
然后表达式 timer.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)());