35

在 Rails 中,我可以这样做:

 x = user.try(:name)

此方法返回nilif useris nilelse user.name。这name是在user对象上定义的方法。

我知道它可以if..then..else在 Javascript 中使用,但是是否有等效的紧凑方法可以在 Javascript 中做同样的事情?

谷歌搜索指向 Javascript 的try命令,这不是我想要的。

4

6 回答 6

47

您可以这样做,因为没有内置的方法:

var x = (user || {}).name;
  • 如果用户未定义/为空,您将获得未定义
  • 如果定义了用户,您将获得名称属性(可能已设置或未定义)。

如果未定义用户(空),这不会破坏脚本。

但是用户变量必须在范围内的某个地方声明,即使它的值没有定义。否则你会得到错误提示用户未定义。

同样,如果在全局范围内,那么您可以显式检查此变量作为全局范围的属性,以避免上述错误

前任:

 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.
于 2013-10-10T01:18:24.390 回答
11

可选的链接运算符

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 解释了如何使用它和其他用例

于 2018-02-26T19:54:40.220 回答
8

您可以使用逻辑 AND ( &&) 运算符。它的工作方式与大多数语言不同,因为它的结果不是 boolean。例如:

const x = user && user.name;

下表显示了使用此运算符的所有可能结果:

+--------------+-----------------------+
|    user      | x = user && user.name |
+--------------+-----------------------+
| undefined    | undefined             |
| null         | null                  |
| {}           | undefined             |
| {name:''}    | ''                    |
| {name:'Jon'} | 'Jon'                 |
+--------------+-----------------------+
于 2017-01-30T00:27:47.723 回答
2

这与在 Javascript 中为您提供的内容不同:

user['name']
user.name

这将返回undefined而不是,nil但在大多数情况下这是等效的。我认为 Rails 需要该try方法的原因是因为您无法访问实例变量,除非它们可以访问。

要添加到@PSL 的方法,我通常会执行以下操作:

var x = user || {},
    y = x.name || {},
    z = y.first_name;
于 2013-10-10T01:26:06.327 回答
2

在 Rails4 中,try这样做

调用名称作为第一个参数的公共方法public_send,只是如果接收者没有响应它,则调用返回 nil 而不是引发异常。

在 Rails3 中,try就像try!在 Rails4 中一样,try除了如果对象不理解您尝试调用的方法时它会抱怨。的初衷try是隐藏一堆nil支票,这样你就可以说:

o.try(:m)

代替

o.nil?? nil : o.m

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, ...)and xwould be (包括 if is or )。nullobjmethod_nameobjnullundefined

演示: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可能'function'在一个 JavaScript 环境中,但我认为不能保证它总是'function'无处不在。不过,主要用途(即隐藏nullundefined检查)应该可以在任何地方使用。

于 2013-10-10T06:04:23.337 回答
0

我不这么认为。为什么不自己滚动?不完全等效,但可以完成工作。

function tryMe(obj) {
  return obj === null || obj === undefined ? null : obj;
}
于 2013-10-10T01:18:26.397 回答