1

所以我有一个伪类,里面有函数和变量。例如:

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();
});
4

4 回答 4

2

一题:

> var _Constructor_ = function () {
>    var mySong = new Song();
>    this.songs = new Array(mySong);
> };
> _Constructor_();

在上面,当_Constructor_作为函数调用时,您没有设置它的this值,因此它默认为全局对象(在非严格模式下,或在严格模式下未定义)。所以songs成为全局变量或在严格模式下抛出错误。

无论如何,这似乎是相当无用的功能,请考虑:

this.songs = [ new mySong() ];
于 2012-05-21T01:28:59.853 回答
1
function MyClass()
{
    this.a = 0;
    this.b = function(c)
    {
        this.a += c;
    }
}

变成a+=c_this.a+=c;

于 2012-05-21T00:45:14.210 回答
1

我看到有人从字面上理解 JavaScript 中的“Java”。:)

关于 JavaScript,你应该知道的几件事:

  1. 在 JavaScript 中,数组不像在其他语言中那样工作。它们更像是字典,而不是你在 C 或 Java 中称为数组的东西。它们并没有显着提高内存效率或速度;没有进行预分配;在低级实现中没有偏移等。JavaScript 数组只不过是一种方便(但很有用!)的结构,用于保存命令式数据。

  2. 可以使用new Array(length)表达式或简单的文字表达式创建数组[]。通常,您需要使用数组字面量[].

  3. 使用new Array(length)并没有真正做任何有用的事情。它设置了数组的初始length属性,但基本上就是这样。所有元素都保留undefined。没有额外的约束或边界检查。您可以a[100] = 'whatever'对通过调用创建的数组进行操作var a = new Array(5) ,并且解释器不会眨眼。

  4. 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_();
}

这段代码可能没有做你认为它正在做的事情。

  1. 通过初始化函数SongDatabase内部的方法,SongDatabase()您正在为每个songDatabase. 当您处理几十个实例时,这可能没什么大不了的,但如果您要处理数百个实例,则所需的额外内存可能会成为问题。您将希望在prototype此处使用该模式(见下文)。
  2. 你的_Constructor_功能没有做任何事情。 var mySong = new Song()创建函数mySong本地的新对象,_Constructor_并且在其外部不可访问。当_Constructor_调用返回时,它的mySong变量被垃圾收集(就像任何其他局部变量一样)。
  3. _Constructor_是私有函数而不是方法;我不完全确定this在这种情况下会参考什么。您最终可能会在全局对象上创建一个歌曲属性(但我想对此进行测试以确定)。
  4. 正如我之前提到的,当您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`
};

The prototypal pattern may look strange, but its probably the best way to handle your use case. You'll still have direct access to then songs array (which may or may not be important), and by attaching the loadSongs and saveSongs functions to SongDatabase's prototype you ensure that those functions are shared.

于 2012-05-21T03:25:38.697 回答
0

变量不像其他语言那样绑定到“类”。将其视为具有属性的对象。一个单一的a只是引用一个变量“a”(没有var在函数中声明,所以在这里甚至是全局的)。您想更新对象的属性“a”,请改用(点运算符访问该属性)。您可能还想阅读使用对象thisthis.a


编辑后(你说你一直在使用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_();
}

构造函数 like SongDatabaseis (使用new关键字)使用新实例调用 as this。一个普通的函数通常被什么都调用,即非严格模式下的thisis或全局对象。undefined请参阅MDN 上的关键字文档this

songs在这里,您首先使用一个空数组初始化 songDatabases 的属性。然后,在_Constructor_函数中,您使用一首歌曲创建另一个数组,但将其分配给window.songs,因为未在 songDatabase 实例上调用该函数。loadSongs()您的方法中可能会出现同样的问题。除了调用和绑定为实例对象提供“静态”引用的常用方法之外,还有一个作用域变量:

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_“类”。

于 2012-05-21T00:48:10.403 回答