JavaScript单例类型错误:为什么严格模式会标记这个
JavaScript singleton type-error: why does strict mode flag this?
我对JavaScript比较陌生,我很难理解为什么会出现这个错误:
TypeError:试图分配给只读属性。 MyTimer.js: 35
我知道这个错误显示是因为我使用严格模式,但是我启用了严格模式来帮助我调试这个对象。
创建MyTimer
单例的调用如下:
var simTimer = new SimTimer();
然后在MyTimer
中添加一个要执行的任务,如下所示:
var task = function(){
console.log("performing task.");
};
simTimer.addTask(task);
最后,这是MyTimer
对象(标记了第35行):
var MyTimer = (function () {
"use strict";
// var timer;
var tasks;
/**
* If an instance of MyTimer exists, it will be saved to this variable and returned
* by any subsequent calls to this constructor, thus only one instance (stored in this
* variable) will be accessible.
* @private
*/
var instance;
/**
* Called to initialize this MyTimer Object, or return #instance if it already contains
* an instance of this Object.
*/
function Singleton() {
if (instance) {
return instance;
}
instance = this;
tasks = $.Callbacks();
this.timer = setInterval(function()
{
this.tasks.fire();
}, 1000);//<---- THIS IS LINE 35!
this.addTask = function(task)
{
this.tasks.add(task);
};
this.removeTask = function(task)
{
this.tasks.remove(task);
};
}
//instance accessor
Singleton.getInstance = function () {
return instance || new Singleton();
};
return Singleton();
}());
我有什么没有领会?我已经阅读了很多关于模块模式的文档,并且已经成功地编写了单例——那么我在这里错在哪里呢?
** EDIT: **
我能够通过删除var tasks
来获得正确的行为,并使用this
在Singleton
中创建它。函数的工作版本现在看起来像这样:
function Singleton() {
if (instance) {
return instance;
}
instance = this;
this.tasks = $.Callbacks();
this.timer = setInterval(function(){
instance.tasks.fire();
}, 1000);
this.removeTask = function(task)
{
instance.tasks.remove(task);
};
this.addTask = function(task)
{
instance.tasks.add(task);
};
}
所以我仍然不完全理解-为什么这个改变修复了它?这到底是一个范围问题吗?
如果我没看错的话,这里有一个作用域问题
this.timer = setInterval(function()
{
this.tasks.fire(); <-- this will be in window scope
}, 1000);
应该是
this.timer = setInterval(function()
{
instance.tasks.fire();
}, 1000);
我认为以下严格的模式限制是解释。
如果在严格模式代码中求值,则this值为没有被强制到一个对象上。如果此值为空或未定义,则不是转换为全局对象,并且不转换原始值包装对象。this值通过函数调用传递(包括使用Function.prototype.apply和Function.prototype.call)不会强制传递这个值给对象(10.4.3,11.1.1,15.3.4.3,15.3.4.4).
当你呼叫
return Singleton();
this
值实际上是未定义的。
return {
getInstance: function () {
return instance || new Singleton();
}
};
不确定这是否是原因,但看起来"tasks = $. callbacks();"应该是"this"。tasks = $. callbacks ();此外,当您提供一个实例作为回调时,您将丢失'this'绑定。你调用任何带有"this."的函数体应该使用一个var来在外部闭包中捕获它(看起来像'instance'所做的)。
例如,这个方法应该是:
。timer = setInterval(函数){instance.tasks.fire ();}, 1000);
- 使用模式格式化Number类型输入中的值
- Mongoose TypeError:实例化模式类型的对象时,对象不是函数
- 如何在javascript对象中设置属性的类型,就像mongoose模式设计一样
- 如何在模式窗口中从html表单文件类型打开图像
- 其他类型的文件上传中的输入模式
- 在无类型语言中是否存在模式匹配之类的东西
- 模块模式中的私有方法:类型错误:未定义不是一个函数
- 处理输入类型文件模式中的按键
- 它是什么类型的Javascript模式
- 为什么正则表达式模式不符合 javascript 数据类型的条件
- 引导模式委托偶数类型语法
- c#asp.net如何使用bootstrap模式将视频源文件名添加到不同的媒体类型中
- 为什么NaN不是json模式基元类型
- 输入类型复选框在引导模式中不起作用
- javascript自定义模式验证类型
- 如何获取JSON对象的模式并输出到包含类型的字符串
- Phonegap构建android禁用home/power/softkeys (kiosk模式类型的应用程序)
- 这个JS遵循什么类型的模式?
- 从输入控件检索特定模式类型的子节点
- 如何确定字符串是否与模式类型匹配