245

例で説明します:

エルビス オペレーター (?: )

「エルビス演算子」は、Java の三項演算子を短縮したものです。これが便利な例の 1 つは、式が false または null に解決された場合に「適切なデフォルト」値を返す場合です。簡単な例は次のようになります。

def gender = user.male ? "male" : "female"  //traditional ternary operator usage

def displayName = user.name ?: "Anonymous"  //more compact Elvis operator

安全航行事業者 (?.)

安全なナビゲーション演算子は、NullPointerException を回避するために使用されます。通常、オブジェクトへの参照がある場合、オブジェクトのメソッドまたはプロパティにアクセスする前に、それが null でないことを確認する必要がある場合があります。これを回避するために、セーフ ナビゲーション オペレータは次のように、例外をスローする代わりに単純に null を返します。

def user = User.find( "admin" )           //this might be null if 'admin' does not exist
def streetName = user?.address?.street    //streetName will be null if user or user.address is null - no NPE thrown
4

22 に答える 22

165

Elvis 演算子の代わりに論理「OR」演算子を使用できます。

たとえばdisplayname = user.name || "Anonymous"

しかし、現在 Javascript には他の機能がありません。別の構文が必要な場合は、 CoffeeScriptを参照することをお勧めします。探しているものに似た略記があります。

たとえば、実存的演算子

zip = lottery.drawWinner?().address?.zipcode

機能のショートカット

()->  // equivalent to function(){}

セクシー関数呼び出し

func 'arg1','arg2' // equivalent to func('arg1','arg2')

複数行のコメントとクラスもあります。明らかに、これをjavascriptにコンパイルするか、ページに挿入する必要<script type='text/coffeescript>'がありますが、多くの機能が追加されます:)。Using<script type='text/coffeescript'>は実際には開発のみを目的としており、本番用ではありません。

于 2011-07-07T16:40:14.197 に答える
138

少し長くなりますが、以下は安全なナビゲーション演算子と同等だと思います。

var streetName = user && user.address && user.address.street;

streetNameuser.address.streetはまたはの値のいずれかになりますundefined

デフォルトで別のものにしたい場合は、上記のショートカットと組み合わせるか、次のように指定できます。

var streetName = (user && user.address && user.address.street) || "Unknown Street";
于 2015-09-04T11:31:23.297 に答える
88

Javascriptの論理OR演算子短絡しており、「エルビス」演算子を置き換えることができます。

var displayName = user.name || "Anonymous";

?.しかし、私の知る限り、あなたのオペレーターに相当するものはありません。

于 2011-07-07T16:36:17.200 に答える
85

私は時折、次のイディオムが役立つことを発見しました。

a?.b?.c

次のように書き換えることができます。

((a||{}).b||{}).c

nullこれは、オブジェクトで不明な属性を取得すると、またはのように例外をスローするのではなく、undefined が返されるという事実を利用しているundefinedため、ナビゲートする前に null と undefined を空のオブジェクトに置き換えます。

于 2016-06-17T15:20:59.303 に答える
25

のように、lodash_.get()がここで役立つと思います。_.get(user, 'name')_.get(o, 'a[0].b.c', 'default-value')

于 2016-01-16T17:35:10.317 に答える
13

前者の場合は、を使用できます||。Javascriptの「論理or」演算子は、単純に固定されたtrue値とfalse値を返すのではなく、trueの場合は左の引数を返し、それ以外の場合は右の引数を評価して返すという規則に従います。真理値のみに関心がある場合は同じように機能しますが、真の値を含むfoo、bar、またはbazの左端のfoo || bar || baz値を返すことも意味します。

ただし、falseとnullを区別できるものは見つかりません。また、0と空の文字列はfalse値であるため、正当に0または。になる可能性のあるvalue || default構文の使用は避けてください。value""

于 2011-07-07T16:36:42.810 に答える
6

以下は、単純な elvis 演算子に相当するものです。

function elvis(object, path) {
    return path ? path.split('.').reduce(function (nestedObject, key) {
        return nestedObject && nestedObject[key];
    }, object) : object;
}

> var o = { a: { b: 2 }, c: 3 };
> elvis(o)

{ a: { b: 2 }, c: 3 }

> elvis(o, 'a');

{ b: 2 }

> elvis(o, 'a.b');

2

> elvis(o, 'x');

undefined
于 2015-07-14T21:10:31.203 に答える
5

次のように言うことで、ほぼ同じ効果を得ることができます。

var displayName = user.name || "Anonymous";
于 2011-07-07T16:36:38.583 に答える
3

これは、null 合体演算子としてより一般的に知られています。Javascriptにはありません。

于 2011-07-07T16:34:15.600 に答える
2

そのための解決策があります。自分のニーズに合わせて調整してください。私のライブラリの 1 つからの抜粋です。

    elvisStructureSeparator: '.',

    // An Elvis operator replacement. See:
    // http://coffeescript.org/ --> The Existential Operator
    // http://fantom.org/doc/docLang/Expressions.html#safeInvoke
    //
    // The fn parameter has a SPECIAL SYNTAX. E.g.
    // some.structure['with a selector like this'].value transforms to
    // 'some.structure.with a selector like this.value' as an fn parameter.
    //
    // Configurable with tulebox.elvisStructureSeparator.
    //
    // Usage examples: 
    // tulebox.elvis(scope, 'arbitrary.path.to.a.function', fnParamA, fnParamB, fnParamC);
    // tulebox.elvis(this, 'currentNode.favicon.filename');
    elvis: function (scope, fn) {
        tulebox.dbg('tulebox.elvis(' + scope + ', ' + fn + ', args...)');

        var implicitMsg = '....implicit value: undefined ';

        if (arguments.length < 2) {
            tulebox.dbg(implicitMsg + '(1)');
            return undefined;
        }

        // prepare args
        var args = [].slice.call(arguments, 2);
        if (scope === null || fn === null || scope === undefined || fn === undefined 
            || typeof fn !== 'string') {
            tulebox.dbg(implicitMsg + '(2)');
            return undefined;   
        }

        // check levels
        var levels = fn.split(tulebox.elvisStructureSeparator);
        if (levels.length < 1) {
            tulebox.dbg(implicitMsg + '(3)');
            return undefined;
        }

        var lastLevel = scope;

        for (var i = 0; i < levels.length; i++) {
            if (lastLevel[levels[i]] === undefined) {
                tulebox.dbg(implicitMsg + '(4)');
                return undefined;
            }
            lastLevel = lastLevel[levels[i]];
        }

        // real return value
        if (typeof lastLevel === 'function') {
            var ret = lastLevel.apply(scope, args);
            tulebox.dbg('....function value: ' + ret);
            return ret;
        } else {
            tulebox.dbg('....direct value: ' + lastLevel);
            return lastLevel;
        }
    },

魅力のように機能します。痛みが少ないことをお楽しみください!

于 2012-02-16T09:50:58.130 に答える
0

これは、いくつかのミックスインを使用した安全なナビゲーション オペレーターにとって興味深いソリューションでした。

http://jsfiddle.net/avernet/npcmv/

  // Assume you have the following data structure
  var companies = {
      orbeon: {
          cfo: "Erik",
          cto: "Alex"
      }
  };

  // Extend Underscore.js
  _.mixin({ 
      // Safe navigation
      attr: function(obj, name) { return obj == null ? obj : obj[name]; },
      // So we can chain console.log
      log: function(obj) { console.log(obj); }
  });

  // Shortcut, 'cause I'm lazy
  var C = _(companies).chain();

  // Simple case: returns Erik
  C.attr("orbeon").attr("cfo").log();
  // Simple case too, no CEO in Orbeon, returns undefined
  C.attr("orbeon").attr("ceo").log();
  // IBM unknown, but doesn't lead to an error, returns undefined
  C.attr("ibm").attr("ceo").log();
于 2016-06-29T14:55:59.717 に答える
-8

個人的に使ってます

function e(e,expr){try{return eval(expr);}catch(e){return null;}};

たとえば、安全な取得:

var a = e(obj,'e.x.y.z.searchedField');
于 2016-12-12T07:56:44.443 に答える