我将举例解释:
猫王运算符(?:)
“猫王运算符”是缩写
Java的三元运算符。一个
这很方便的例子是
返回一个“合理的默认值”
如果表达式解析为false或
null。一个简单的例子是这样的
这样的:
def gender = user.male ? "male" : "female" //traditional ternary operator usage
def displayName = user.name ?: "Anonymous" //more compact Elvis operator
安全导航操作员(?.)
使用安全导航操作符
来避免NullPointerException。
通常当你有一个参考
您可能需要验证的对象
在访问前它不是空的
对象的方法或属性。
为了避免这种情况,安全航行
运算符将简单地返回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
2020年更新
JavaScript现在有了Elvis操作符和安全导航操作符的等价物。
安全出入物业
可选的链接运算符(?.)目前是ECMAScript第四阶段的提案。你今天可以用它来对付巴别塔。
// `undefined` if either `a` or `b` are `null`/`undefined`. `a.b.c` otherwise.
const myVariable = a?.b?.c;
逻辑与运算符(&&)是处理这种情况的“旧的”、更冗长的方法。
const myVariable = a && a.b && a.b.c;
提供默认值
空合并运算符(??)目前是第4阶段的ECMAScript提案。你今天可以用它来对付巴别塔。如果运算符的左边是一个空值(null/undefined),它允许您设置一个默认值。
const myVariable = a?.b?.c ?? 'Some other value';
// Evaluates to 'Some other value'
const myVariable2 = null ?? 'Some other value';
// Evaluates to ''
const myVariable3 = '' ?? 'Some other value';
逻辑或运算符(||)是一种行为略有不同的替代解决方案。它允许您在操作符左侧为假值时设置默认值。注意下面的myVariable3的结果与上面的myVariable3不同。
const myVariable = a?.b?.c || 'Some other value';
// Evaluates to 'Some other value'
const myVariable2 = null || 'Some other value';
// Evaluates to 'Some other value'
const myVariable3 = '' || 'Some other value';
你可以自己卷:
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) {
break;
}
}
return returnObject;
};
像这样使用它:
var result = resolve(obj, 'a.b.c.d');
*如果a, b, c或d中的任何一个未定义,则结果未定义。
这是一个有趣的解决方案,安全导航操作员使用一些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();
这个问题困扰了我很长一段时间。我必须想出一个解决方案,一旦我们得到猫王运算符或其他东西,就可以很容易地迁移。
这就是我用的;适用于数组和对象
把这个放到tools.js文件里
// this will create the object/array if null
Object.prototype.__ = function (prop) {
if (this[prop] === undefined)
this[prop] = typeof prop == 'number' ? [] : {}
return this[prop]
};
// this will just check if object/array is null
Object.prototype._ = function (prop) {
return this[prop] === undefined ? {} : this[prop]
};
使用的例子:
let student = {
classes: [
'math',
'whatev'
],
scores: {
math: 9,
whatev: 20
},
loans: [
200,
{ 'hey': 'sup' },
500,
300,
8000,
3000000
]
}
// use one underscore to test
console.log(student._('classes')._(0)) // math
console.log(student._('classes')._(3)) // {}
console.log(student._('sports')._(3)._('injuries')) // {}
console.log(student._('scores')._('whatev')) // 20
console.log(student._('blabla')._('whatev')) // {}
console.log(student._('loans')._(2)) // 500
console.log(student._('loans')._(1)._('hey')) // sup
console.log(student._('loans')._(6)._('hey')) // {}
// use two underscores to create if null
student.__('loans').__(6)['test'] = 'whatev'
console.log(student.__('loans').__(6).__('test')) // whatev
好吧,我知道这使代码有点难以阅读,但这是一个简单的一行解决方案,工作出色。我希望它能帮助到一些人:)
这是一个简单的猫王运算符等价:
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