1

以下のコードで何が起こっているのか誰か説明できますか? toString が foo と bar の両方で呼び出されるか、どちらも呼び出されないことを期待します。リテラル オブジェクト表記法は、作成後にオブジェクトにフィールドを追加することとどう違うのですか?

function Obj(v) {
    this.v = v;    
};

Obj.prototype.toString= function() {
    window.alert("to string called for " +
                this.v);
    return this.v.toString();
}        

var foo = new Obj('foo');
var bar = new Obj('bar');

// toString is not called here.
var map = {foo : 'blah'};
// toString is called here.
map[bar] = "blah2";

既存のオブジェクトへの追加ではtoString()を使用するのに、オブジェクトリテラルではtoString()を使用しないのはなぜですか?

http://jsfiddle.net/pByGJ/2/

4

2 に答える 2

3

オブジェクト リテラルがコロンの左側の識別子を評価しない主な理由は、(JSON の場合のように) すべてのリテラル名を引用する必要がないためです。

ブラケット表記では、プロパティ名を引用する必要があります。引用しない場合、変数として評価されます。

toString()2 番目の例で呼び出される理由はbar、プロパティ名として使用する文字列に変換する必要があるためです。

最初の例では、リテラル オブジェクトを作成しているだけです (これは とまったく同じ {"foo" : 'blah'}です)。つまり、変数を使用することはありませんfoo

[]変数名を使用してオブジェクトを作成する場合は、リテラルオブジェクト表記を使用できません。toString()

1 つの式で変数名を持つオブジェクトを作成する関数を次に示します。

function obj(key, value /*, key, value, ... */) {
    var obj = {};
    for (var i = 0, ln = arguments.length ; i < ln; i+=2) {
        obj[arguments[i]] = arguments[i+1];
    }
    return obj;
}

より明確な例

変数名と値が同じであるという事実は、問題を理解するのに役立ちません。このコードを提案させてください

var foo = new Obj('fooValue');
var bar = new Obj('barValue');

var map = {foo : 'blah'};
map[bar] = "blah2";

// You expect map to be {fooValue: 'blah', barValue: 'blah2'}
// But it's {foo: 'blah', barValue: 'blah2'}

必要なことをするには、私のobj機能を使用してください

// Almost as clear as literal notation ???
var map = obj(
    foo, 'blah',
    bar, 'blah2'
);
// map = {fooValue: 'blah', barValue: 'blah2'} Yay!!
于 2012-10-26T18:34:03.690 に答える
2

オブジェクト リテラルのキーは文字列として取得され、変数として解釈されません。これ:

var map = {foo : 'blah'};

これと同等です:

var map = {"foo" : 'blah'};

この:

var map = {};
map["foo"] = "blah";

しかし、これとは完全に異なります:

var map = {};
map[foo] = "blah";
于 2012-10-26T18:45:34.847 に答える