2

obj次のように定義された変数があります。

{user: {username: "AzureDiamond", password: "hunter2"}}

str次の文字列のいずれかとして定義される可能性のある文字列があります。

  • "ユーザー"
  • 「ユーザー[ユーザー名]」
  • "利用者パスワード]"
  • "偽"

JS (具体的には node.js) で次のことを基本的/動的に実行するための比較的簡単な方法はありますか?

  • str == "user"返却の場合{username: "AzureDiamon", password: "hunter2"}
  • の場合str == "user[username]"、「AzureDiamond」を返します
  • の場合str == "user[password]"、「hunter2」を返します
  • str == "fake"返却の場合null

編集:この質問は、正規表現の一致以外に使用できる、より簡単な JS/node.js に組み込まれたものがあるかどうかを調べるためのものです。

4

3 に答える 3

4

解決

の構文strが正しいことが確実な場合、関数は次のようになります。

function get_by_path(source, path){
    var path_elements = path.split(']').join('').split('[');
    for (var i=0; i < path_elements.length; i++){
        source = source[path_elements[i]];
        if (typeof source === 'undefined'){
            return null;
        }
    };
    return source;
};

テスト

動作は次のとおりです。

var data = {'user': {
    'username': "AzureDiamond", 'password': "hunter2",
    'details': {'address': {'street': "Happiness Street"}}
}};

get_by_path(data, 'user');                           // gives user object
get_by_path(data, 'user[username]');                 // gives "hunter2"
get_by_path(data, 'user[password]');                 // gives "AzureDiamond"
get_by_path(data, 'fake');                           // gives null
get_by_path(data, 'user[details][address][street]'); // gives "Happiness Street"

説明

スクリプトは正規表現も危険な呼び出しも使用せず、「パス」は角かっこなしの1つの単語で始まり、次のすべての部分(存在する場合)は角かっこで囲まれた単語であるとeval()想定します。トラバースされたオブジェクト内にパスが見つからない場合は、が返されます。見つかった場合は、返されます(複雑なオブジェクト、文字列、ブール値などに関係なく)。nullnull

スクリプトは、パスを解析することから始まります。これは、閉じ角かっこ( " ]")を削除し、角かっこ( "")を開いて結果の文字列を分割することによって行われます[。プロセスは次のようになります。

"user"                  -> "user"                -> ["user"]
"user[username]"        -> "user[username"       -> ["user", "username"]
"user[password]"        -> "user[password"       -> ["user", "password"]
"user[address][street]" -> "user[address[street" -> ["user", "address", "street"]
"fake"                  -> "fake"                -> ["fake"]

したがって、ご覧のとおり、最後にパス要素の配列があります。これらは1つずつ評価されます。いずれかのレベルで適切なステップをデータ引数の構造に深く入れることができない場合は、nullが返されます。それ以外の場合は、最後にアクセスされた要素が返されます。

証拠

それが機能することの証明はここにあります:http://jsfiddle.net/EJCgE/2/

編集replace():文字列のメソッドがどのように機能するかに起因して、より複雑なパス(3つ以上のレベルがある場合)にいくつかの問題がありました。jQueryを含まないようにコードを更新し、その問題を修正しました。

EDIT2:冗長な行と1つの冗長な変数を削除するようにスクリプトを更新しました。

于 2012-06-16T02:41:49.590 に答える
2

これは EXTJS3 ソース コードから直接取得したものですが、同様のことを行うために何度も使用しています。

createAccessor : function(){
    var re = /[\[\.]/;
    return function(expr) {
        if(Ext.isEmpty(expr)){
            return Ext.emptyFn;
        }
        if(Ext.isFunction(expr)){
            return expr;
        }
        var i = String(expr).search(re);
        if(i >= 0){
            return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
        }
        return function(obj){
            return obj[expr];
        };

    };
}(),

これを次のように使用します。

var accessor = createAccessor(str);
var data = accessor(object);
于 2012-06-16T02:28:07.753 に答える
0

機能をお試しくださいeval。文字列を受け取り、その文字列を JavaScript コードであるかのように実行します。例えば:

var data = {user: {username: "AzureDiamond", password: "hunter2"}};
var str = "user[\"password\"]";
console.log( eval("data." + str) );
// Prints "hunter2"

ただし、これには非常に注意する必要があります。なぜなら、それがどこからstr来たのかによって、人々は本質的にあなたのサーバー上でコードをリモートで実行する可能性があるからです. 正規表現を使用して、実行前に文字列を検証し、人々があなたに卑劣な情報を送信したり、サーバーをハッキングしたりできないようにします。

password編集:実行時に変数ではなく文字列として扱われるように、 引用する必要があることに注意してください。

于 2012-06-16T02:25:19.407 に答える