utiliza que funciona español ejemplos definicion como caracteristicas javascript jquery groovy safe-navigation-operator

que - javascript pdf



¿Hay un operador de navegación nula(Elvis) o un operador de navegación seguro en javascript? (14)

Explicaré con el ejemplo:

Operador de Elvis (?:)

El "operador de Elvis" es un acortamiento del operador ternario de Java. Una instancia de donde esto es útil es para devolver un valor "predeterminado sensible" si una expresión se resuelve como falsa o nula. Un ejemplo simple podría verse así:

def gender = user.male ? "male" : "female" //traditional ternary operator usage def displayName = user.name ?: "Anonymous" //more compact Elvis operator

Operador de navegación segura (?.)

El operador Safe Navigation se usa para evitar una NullPointerException. Normalmente, cuando tiene una referencia a un objeto, es posible que necesite verificar que no sea nulo antes de acceder a los métodos o las propiedades del objeto. Para evitar esto, el operador de navegación segura simplemente devolverá nulo en lugar de lanzar una excepción, así:

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



Aquí hay un simple operador de elvis equivalente:

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


Creo que lo siguiente es equivalente al operador de navegación segura, aunque un poco más:

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

streetName será el nombre de la calle o null / undefined.

Si quieres que sea predeterminado para otra cosa, puedes combinarlo con el atajo anterior o para dar:

var streetName = (user && user.address && user.address.street) || "Unknown Street";


Creo que lodash _.get() puede ayudar aquí, como en _.get(user, ''name'') , y tareas más complejas como _.get(o, ''a[0].b.c'', ''default-value'')


El operador lógico O de Javascript está short-circuiting y puede reemplazar a su operador "Elvis":

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

Sin embargo, que yo sepa, no hay equivalente a su ?. operador.


Esta fue una solución interesante para el operador de navegación segura que utilizaba algunos mixin ..

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


Esto es más comúnmente conocido como un operador nulo-coalescente. Javascript no tiene uno.


Ocasionalmente, he encontrado el siguiente modismo útil:

a?.b.?c

puede ser reescrito como:

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

Esto aprovecha el hecho de que obtener atributos desconocidos en un objeto no es definido, en lugar de arrojar una excepción como lo hace en null o undefined , por lo que reemplazamos nulos y sin definir con un objeto vacío antes de navegar.


Para el primero, puedes usar || . El operador "lógico o" de Javascript, en lugar de simplemente devolver valores verdaderos y falsos enlatados, sigue la regla de devolver su argumento de la izquierda si es verdadero, y de lo contrario evalúa y devuelve su argumento correcto. Cuando solo te interesa el valor de verdad, funciona igual, pero también significa que foo || bar || baz foo || bar || baz foo || bar || baz devuelve el más a la izquierda de foo, bar o baz que contiene un valor verdadero .

Sin embargo, no encontrará uno que pueda distinguir entre falso y nulo, y 0 y cadena vacía son valores falsos, así que evite usar el value || default construcción value || default donde el value puede ser legítimamente 0 o "" .


Personalmente uso

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

y por ejemplo, obtener seguro:

var a = e(obj,''e.x.y.z.searchedField'');


Puede lograr aproximadamente el mismo efecto diciendo:

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


Puede usar el operador lógico ''OR'' en lugar del operador de Elvis:

Por ejemplo displayname = user.name || "Anonymous" displayname = user.name || "Anonymous" .

Pero Javascript actualmente no tiene la otra funcionalidad. Yo recomendaría mirar CoffeeScript si quieres una sintaxis alternativa. Tiene una forma abreviada que es similar a lo que estás buscando.

Por ejemplo, The Existenntial Operator

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

Atajos de funciones

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

Llamada de función atractiva

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

También hay comentarios y clases de líneas múltiples. Obviamente, tiene que compilar esto para javascript o insertar en la página como <script type=''text/coffeescript>'' pero agrega mucha funcionalidad :). Usar <script type=''text/coffeescript''> realidad solo está destinado al desarrollo y no a la producción.


Tengo una solución para eso, adaptarla a tus propias necesidades, un extracto de una de mis libs:

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; } },

Funciona de maravilla. Disfruta el menos dolor!


Usted puede hacer su propio:

function resolve(objectToGetValueFrom, stringOfDotSeparatedParameters) { var returnObject = objectToGetValueFrom, parameters = stringOfDotSeparatedParameters.split(''.''), i, parameter; for (i = 0; i < parameters.length; i++) { parameter = parameters[i]; returnObject = returnObject[parameter]; if (returnObject === undefined) { return undefined; } } return returnObject; };

Y la usa así:

var result = resolve(obj, ''a.b.c.d'');

* el resultado no está definido. Cualquiera de a, b, c o d no está definido