所以我有一个伪类,里面有函数和变量。例如:
function MyClass()
{
this.a = 0;
this.b = function(c)
{
this.a += c;
}
}
然后,当我稍后使用它时,我会这样做:
var myObject = new MyClass();
myObject.b(3);
myObject.b(5);
但是当我这样做时:
console.log("A: " + myObject.a);
我明白了:
A: 0
我做错了什么?
这是我的实际代码。它被分成多个文件,但我会提出相关的文件:
function SongDatabase() {
this.songs = new Array();
this.loadSongs = function () {
};
this.saveSongs = function () {
};
var _Constructor_ = function () {
var mySong = new Song();
this.songs = new Array(mySong);
};
_Constructor_();
}
function LyriX() {
var songDatabase = new SongDatabase();
//var playlistDatabase = new PlaylistDatabase();
songDatabase.loadSongs();
var sourceList = new ScrollableList();
sourceList.setElement($S.getElement("sourceList"));
var accessoryList = new ScrollableList();
accessoryList.setElement($S.getElement("accessoryList"));
var sourceListClick = function (index) {
$S.log("source click: " + index);
if (index == 0) {
displaySongs();
}
};
sourceList.setClickListener(sourceListClick);
var displaySongs = function () {
$S.log("display songs");
// STACK OVERFLOW LOOK HERE!!! thanks :)
// in debug in chrome songDatabase.songs is a zero length array
accessoryList.loadArray(songDatabase.songs);
};
}
$S.addOnLoadListener(function () {
new LyriX();
});
答案 0 :(得分:2)
一个问题:
> var _Constructor_ = function () {
> var mySong = new Song();
> this.songs = new Array(mySong);
> };
> _Constructor_();
在上面,当_Constructor_
作为函数调用时,不设置其this
值,因此它默认为全局对象(在非严格模式下,或在严格模式下未定义) )。因此songs
成为全局变量或在严格模式下抛出错误。
无论如何,这似乎是相当无用的功能,请考虑:
this.songs = [ new mySong() ];
答案 1 :(得分:1)
function MyClass()
{
this.a = 0;
this.b = function(c)
{
this.a += c;
}
}
将a+=c
更改为this.a+=c;
答案 2 :(得分:1)
我看到有人在JavaScript中使用“Java”。 :)
您应该了解的有关JavaScript的一些事情:
在JavaScript中,数组不像其他语言那样工作。 它们更像是字典,然后你用C或Java称为数组; 它们没有更高的内存效率或更快; 没有预先分配; 在低级实现中没有任何缺陷等。 JavaScript数组只是一个方便(但有用!)的结构 用于保存订单命令数据。
可以使用new Array(length)
表达式创建数组,
或简单的文字表达式[]
。
通常,您需要使用数组文字[]
。
使用new Array(length)
并没有真正做任何有用的事情;
它设置了数组的初始length
属性,但基本上就是这样。
所有元素都保持undefined
。
没有其他约束或边界检查。
您可以通过调用a[100] = 'whatever'
创建的数组var a = new Array(5)
并且口译员不会睁大眼睛。
JavaScript使用的原型继承与明显不同 在C ++和Java等语言中使用的经典继承模型。
考虑到这些要点,让我们检查以下代码块:
function SongDatabase() {
this.songs = new Array();
this.loadSongs = function () {
// etc.
};
this.saveSongs = function () {
// etc.
};
var _Constructor_ = function () {
var mySong = new Song();
this.songs = new Array(mySong);
};
_Constructor_();
}
这段代码可能没有按照您的想法进行。
SongDatabase
函数中的SongDatabase()
方法
您正在为songDatabase
的每个实例创建新的方法函数。
当你处理几十个实例时,这可能不是什么大问题,
但如果您正在处理数百,则所需的额外内存可能会成为一个问题。
您可以在此处使用prototype
模式(请参阅下文)。_Constructor_
功能没有做任何事情。
var mySong = new Song()
创建一个新的mySong
对象
_Constructor_
功能的本地功能和无法在其外部访问。
当_Constructor_
调用返回时,
它的mySong
变量是垃圾收集的(就像任何其他局部变量一样)。_Constructor_
是私人功能,不是方法;
我不完全确定该上下文中的this
将引用什么。
您最终可能会在全局对象上创建一个歌曲属性
(但我想测试一下这一点。)Array()
运算符致电new
时
它需要一个可选参数来设置数组的初始length
。
在这种情况下,解释器会尝试将mySong
强制转换为数字
(mySong
不添加到数组中!);
如果失败,它将只返回一个带有length = 0
的新数组。相反,你最好这样写SongDatabase()
:
function SongDatabase() {
this.songs = [];
// etc.
}
SongDatabase.prototype.loadSongs = function () {
// load songs into `this.songs`
};
SongDatabase.prototype.saveSongs = function () {
// save songs loaded into `this.songs`
};
原型模式可能看起来很奇怪,
但它可能是处理您的用例的最佳方式。
您仍然可以直接访问songs
数组(可能重要也可能不重要),
并将loadSongs
和saveSongs
函数附加到SongDatabase
的原型
确保共享这些功能。
答案 3 :(得分:0)
与其他语言一样,变量不会绑定到“类”。将其视为具有属性的对象。单个a
只引用变量“a”(在函数中没有用var
声明,所以在这里甚至全局)。您想要更新this
对象的属性“a”,而是使用this.a
(dot operator来访问该属性)。您也可以阅读Working with objects。
编辑后(您说您一直在使用this.a
),它适用于我:http://jsfiddle.net/WKuZe/
在您向我们提供了真实的代码之后,我注意到了这个奇怪的结构:
function SongDatabase() {
this.songs = new Array();
// some methods
var _Constructor_ = function () {
var mySong = new Song();
this.songs = new Array(mySong);
};
_Constructor_();
}
SongDatabase
之类的构造函数(使用new
关键字)调用新实例为this
。普通函数通常不会被调用,即this
是undefined
或非严格模式下的全局对象。请参阅documentation for the this
keyword on MDN。
在这里,首先使用空数组初始化songDatabases'songs
属性。然后,在_Constructor_
函数中,您创建一个包含一首歌曲的其他数组,但将其分配给window.songs
,因为该函数在songDatabase实例上不是called。您的loadSongs()
方法可能会出现同样的问题。除了调用和binding之外,为实例对象提供“静态”引用的常用方法是一个范围变量:
function SongDatabase() {
var that = this; // <== always points to the instance
// some methods
function _Constructor_ () {
var mySong = new Song();
that.songs = new Array(mySong);
// ^^^^
};
_Constructor_();
}
如果_Constructor_
不是本地函数,但可能是添加接口的全局函数,则可以提供实例(this
)作为参数或使用_Constructor_.call(this)
,这允许使用this
关键字就像_Constructor_
是“类”一样。