在Rails中,我可以这样做:
x = user.try(:name)
如果nil
为user
其他nil
,则此方法会返回user.name
。这里name
是在user
对象上定义的方法。
我知道可以在Javascript中使用if..then..else
来完成,但是在Javascript中是否有相同的 compact 方法来执行相同操作?
谷歌搜索指向Javascript的try
命令,这不是我要找的。 p>
答案 0 :(得分:41)
你可以这样做,因为没有内置的方法:
var x = (user || {}).name;
如果未定义用户(null),则不会破坏脚本。
但是必须在范围内的某个位置声明用户变量,即使其值未定义。否则,您将得到错误的说明用户未定义。
同样,如果在全局范围内,那么您可以显式检查此变量作为全局范围的属性,以避免上述错误
前:
var x = (window.user || {}).name; // or var x = (global.user || {}).name;
为了安全执行功能,
var noop = function(){}; //Just a no operation function
(windowOrSomeObj.exec || noop)(); //Even if there is no property with the name `exec` exists in the object, it will still not fail and you can avoid a check. However this is just a truthy check so you may want to use it only if you are sure the property if exists on the object will be a function.
答案 1 :(得分:7)
您可以使用逻辑AND(&&
)运算符。它的工作方式与大多数语言不同,因为它的结果是不是布尔值。例如:
const x = user && user.name;
下表显示了使用此运算符的所有可能结果:
+--------------+-----------------------+
| user | x = user && user.name |
+--------------+-----------------------+
| undefined | undefined |
| null | null |
| {} | undefined |
| {name:''} | '' |
| {name:'Jon'} | 'Jon' |
+--------------+-----------------------+
答案 2 :(得分:6)
a new proposal for ECMAScript。
它处于早期阶段,但我们可以开始使用它与巴贝尔。
这是问题所在:
<input type="checkbox" id="BrandMeasurement{{$index}}" ng-click="msrmntSelector(grmnt)" />
<label for="BrandMeasurement{{$index}}">Brand Measurement</label>
这是它的工作原理:
const person = {name: 'santiago'}
let zip = person.address.zip // Cannot read property 'zip' of undefined
要开始使用它,我们需要babel alpha 7:
const person = {name: 'santiago'}
let zip = person?.address?.zip // undefined
我们需要将插件添加到.babelrc
npm install --save-dev babel-cli@7.0.0-alpha.19
npm install --save-dev babel-plugin-transform-optional-chaining@^7.0.0-alpha.13.1
Adam Bene Medium Post which explains how to use it and another use cases
答案 3 :(得分:1)
这与Javascript中给你的不一样:
user['name']
user.name
这会返回undefined
而不是nil
,但在大多数情况下都是等效的。我认为Rails需要try
方法的原因是因为除非可以访问实例变量,否则无法访问它们。
要添加到@ PSL的方法,我通常会这样做:
var x = user || {},
y = x.name || {},
z = y.first_name;
答案 4 :(得分:1)
在Rails4中,try
does this:
调用名称作为第一个参数的公共方法,就像
public_send
一样,除非接收者没有响应,否则调用返回nil而不是引发异常。
在Rails3中,try
与Rails4中的try!
类似,并且与try
相同,只是如果对象不理解您尝试调用的方法,则会抱怨。 try
的原意是隐藏一堆nil
支票,以便您可以说:
o.try(:m)
而不是
o.nil?? nil : o.m
Rails4版本还会隐藏检查对象是否理解您要调用的方法。
在JavaScript中没有特殊的语法,但你可以将丑陋扫描成一个函数。
try
的Rails4版本在JavaScript中看起来像这个函数:
function rtry(obj, m) {
if(obj == null)
return null;
if(typeof obj[m] === 'function')
return obj[m].apply(obj, [].slice.call(arguments, 2));
return null;
}
如果x = rtry(obj, 'method_name', arg1, arg2, ...)
不理解x
(包括null
,您会说obj
和method_name
之类的内容会obj
}是null
或undefined
)。
演示:http://jsfiddle.net/ambiguous/BjgjL/
Rails3版本很简单,只需null
检查:
function rtry(obj, m) {
if(obj == null)
return null;
return obj[m].apply(obj, [].slice.call(arguments, 2));
}
并且JavaScript本身会引发obj
的例外,但没有m
方法。此版本相当于CoffeeScript的?
存在运算符的“它是函数”版本。
演示:http://jsfiddle.net/ambiguous/FQCS2/
像往常一样,如果您处理的是本机方法而不是使用JavaScript编写的方法,那么事情可能就不那么好了。 typeof (6).toString
在一个JavaScript环境中可能是'function'
,但我认为不能保证在任何地方始终都是'function'
。主要用途(即隐藏null
和undefined
检查)应该可以在任何地方使用。
答案 5 :(得分:0)
我不这么认为。为什么不自己滚?不完全相同,但做的工作。
function tryMe(obj) {
return obj === null || obj === undefined ? null : obj;
}