2016-11-24 4 views
1
var x = {} 
x['hello'] = {"what": "world"} 
alert(x['hello'].what) 

要素 'hello'が明示的に設定されているために機能します。まだ定義されていない要素のプロパティを設定し、その場で作成するにはどうすればよいですか?

私はまだいない。これはTypeError: Cannot set property 'what' of undefinedでFAIS要素を設定し、その場でそれを作成し、

var x = {} 
x['hello']['what'] = "world" 

のようなもののproertyを定義したいと思います。

Pythonでcollections.defaultdictを使用するのと同じように、このようなケースを処理する方法はありますか?

+0

いいえ、私はJavascriptがこれを持っているとは思いません。 – Barmar

+0

良い古いPerlishの自動化。 Javascriptではありません。しかし、なぜあなたは本当にそれが必要なのですか? – Thilo

+1

ワンライナーの強迫観念は何ですか?改行がなくなっていますか? – Barmar

答えて

0

Object.setPrototypeOf(x, {"what": "world"})をお試しください。それはあなたのために働くのですか?

または「hello」の場合はObject.setPrototypeOf({}, {"hello": {"what": "world"}})を使用してください。

+0

になります。世界 "}})、あなたはあなたが望むほど深く行くことができます。 –

+1

ありがとうございますが、問題は毎回オブジェクト全体を再作成することです。言い換えれば、最初のエントリを上書きすることなく2回使用することはできません。 – WoJ

+0

if(!myObject){//私のことをする}しかし、私は試しました:) –

1

これはやや粗悪なものですが、改良が必要な場合もありますが、最初にaを分割する関数を使用することができます。あなたのためにネストされたサブオブジェクトを作成します。このような何かが

function setObjValue(obj, nesting, value) { 
    var nestArr = Array.isArray(nesting) ? nesting : (nesting.indexOf(".") > -1) ? nesting.split(".") : [nesting], 
     len = nestArr.length,    
     i = 0, 
     cur = obj; 

    for (; i < len; i++) { 
    if (i === len-1) { 
     cur[nestArr[i]] = value; 
    } else { 
     if (!cur[nestArr[i]]) cur[nestArr[i]] = {}; 
     cur = cur[nestArr[i]]; 
    } 
    } 
} 

が次に使用する働き

var a = {}; 
setObjValue(a, "hello.what", "world"); 
//OR 
setObjValue(a, ["hello", "what"], "world"); 
console.log(a); //{hello:{ what: "world" }}; 

UPDATE: 私は上記の機能と、既に設定され、それらのキーを持つオブジェクトを処理するためのフィドルを更新しましたし、それも受け付けます入れ子の引数を配列として返します。

JSFiddle

+0

入れ子は配列です。 'setObjValue(a、[" hello "、" what "]、" world ");' – Thilo

+1

Yupは単純なチェックを追加し、両方のシナリオを許可することができます。配列への変換は非常に簡単です。主にOPをどこに行くかのアイデアを示しています。 –

0

あなたはProxyを使用しますが、サポートはグローバルではないことに注意してくださいすることができます。

エッジケースも考慮する必要があります。以下は、JSでdefaultdictの非常に単純な(そして潜在的にナイーブ)実装です:

function makeDefaultDictFor(obj) { 
 
    // Protect against infinite recursion for 
 
    // intentionally nonexistng properties 
 
    let bannedKeys = [Symbol.toPrimitive, Symbol.iterator, "toJSON"]; 
 
    
 
    // Create a proxy that returns a new object for any missing keys. 
 
    // The returned object also has the same behaviour, so you can 
 
    // nest infinitely deep. 
 
    return new Proxy(obj, { 
 
    get: (target, prop) => { 
 
     if (bannedKeys.indexOf(prop) >= 0) return; 
 
     
 
     // Return existing values when possible 
 
     if (prop in target) return target[prop]; 
 
     
 
     // Make a proxy like this one for undefined keys. 
 
     let newProxy = makeDefaultDictFor({}); 
 
     // Save the object as a property in this object. 
 
     target[prop] = newProxy; 
 
     
 
     return newProxy;  
 
    } 
 
    }); 
 
} 
 

 
let obj = makeDefaultDictFor({}); 
 
obj.hello.world = "!"; 
 
document.write("<pre>"); 
 
document.write(JSON.stringify(obj)); 
 
document.write("</pre>");

関連する問題