Javascript相当于Rails的try方法
在Rails中我可以这样做:
x = user.try(:name)
如果user
为nil
else user.name
则此方法返回nil
。 这里name
是在user
对象上定义的方法。
我知道可以在Javascript中使用if..then..else
来完成,但是在Javascript中是否有相同的紧凑方法来做同样的事情?
谷歌搜索指向Javascript的try
命令,这不是我想要的。
你可以这样做,因为没有内置的方法:
var x = (user || {}).name;
- 如果未定义用户/ null,则将未定义
- 如果定义了user,您将获得name属性(可以设置或未定义)。
如果未定义用户(null),则不会破坏脚本。
但是必须在范围内的某个位置声明用户变量,即使其值未定义。 否则你会得到错误的说用户没有定义。
类似地,如果在全局范围内,则可以显式检查此变量作为全局范围的属性,以避免上述错误
例如:
var x = (window.user || {}).name; // or var x = (global.user || {}).name;
为了安全执行function,
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.
您可以使用逻辑AND( &&
)运算符。 它的工作方式与大多数语言不同,因为它的结果不是布尔值 。 例如:
const x = user && user.name;
下表显示了使用此运算符的所有可能结果:
+--------------+-----------------------+ | user | x = user && user.name | +--------------+-----------------------+ | undefined | undefined | | null | null | | {} | undefined | | {name:''} | '' | | {name:'Jon'} | 'Jon' | +--------------+-----------------------+
可选的链接运算符
是ECMAScript的新提案 。
它处于早期阶段,但我们可以开始使用它与babel。
这就是问题:
const person = {name: 'santiago'} let zip = person.address.zip // Cannot read property 'zip' of undefined
这是它的工作原理:
const person = {name: 'santiago'} let zip = person?.address?.zip // undefined
要开始使用它,我们需要babel alpha 7:
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
我们需要将插件添加到我们的.babelrc中
{ "plugins": ["transform-optional-chaining"] }
Adam Bene Medium Post解释了如何使用它和另一个用例
这与在Javascript中为您提供的内容不同:
user['name'] user.name
这将返回undefined
而不是nil
但在大多数情况下这是等效的。 我认为Rails需要try
方法的原因是因为除非可以访问实例变量,否则无法访问它们。
要添加到@ PSL的方法,我通常会这样做:
var x = user || {}, y = x.name || {}, z = y.first_name;
在Rails4中, try
这样做 :
调用名称作为第一个参数的公共方法,就像
public_send
一样,除了如果接收者没有响应它,则调用返回nil而不是引发exception。
在Rails3中, try
就像try!
一样try!
在Rails4中,这和try
一样,只是如果对象不理解你试图调用的方法,它就会抱怨。 try
的最初目的是隐藏一堆nil
检查,以便您可以说:
o.try(:m)
代替
o.nil?? nil : om
如果对象理解您要调用的方法,Rails4版本还会隐藏检查。
在JavaScript中没有特殊的语法,但你可以将丑陋的东西扫成一个函数。
Rails4版本的try
在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, ...)
,如果obj
不理解method_name
(包括obj
为null
或undefined
), x
将为null
。
演示: 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
检查)应该可以在任何地方使用。
我不这么认为。 为什么不自己滚? 不完全相同但完成工作。
function tryMe(obj) { return obj === null || obj === undefined ? null : obj; }