ruby Rails try方法的Javascript对等用法

aamkag61  于 2022-11-04  发布在  Ruby
关注(0)|答案(6)|浏览(166)

在Rails中,我可以这样做:

x = user.try(:name)

如果usernil,则此方法返回nil,否则返回user.name。这里的name是在user对象上定义的方法。
我知道可以在Javascript中使用if..then..else来完成,但是在Javascript中有没有等效的compact方法来完成同样的任务?
谷歌指向Javascript的try命令,这不是我要找的。

ecfdbz9o

ecfdbz9o1#

您可以使用optional chaining
示例:

// Access Properties

user?.name; // user might be null/undefined

user.name?.firstName // user will be available however name is not guaranteed.

// Access array values

addresses?.[index]; // array addresses might be undefined

// May be function??

user.getGeolocation?.(); // If the function exists execute it.

另一个特性Nullish coalescing operator ??与null/undefined的处理略有不同,但与之相关

// Example:

function foo(input) // some Array as input {
   //.. Some stuff
   return [input??[]].concat(bar); //if input is empty ignore and concat bar on an empty array and return.
}

//----

const defaultVal = 'someVal';
...
const val = this.someObj.prop1??defaultVal;
  • 以下是在Javascript原生可选链接之前的过时解决方案:*

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

var x = (user || {}).name;
  • 如果用户未定义/为空,则将得到undefined
  • 如果定义了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.
w8rqjzmb

w8rqjzmb2#

选择性链接运算子

a new proposal for ECMAScript
这是在一个早期阶段,但我们可以开始使用它与巴别塔。
这就是问题所在:

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

要开始使用它,我们需要巴别塔阿尔法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 which explains how to use it and another use cases

ykejflvf

ykejflvf3#

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

const x = user && user.name;

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

+--------------+-----------------------+
|    user      | x = user && user.name |
+--------------+-----------------------+
| undefined    | undefined             |
| null         | null                  |
| {}           | undefined             |
| {name:''}    | ''                    |
| {name:'Jon'} | 'Jon'                 |
+--------------+-----------------------+
5w9g7ksd

5w9g7ksd4#

这和Javascript中的代码是一样的:

user['name']
user.name

这将返回undefined而不是nil,但在大多数情况下这是等效的。我认为Rails需要try方法的原因是因为您无法访问示例变量,除非它们是可访问的。
为了补充@PSL的方法,我通常会这样做:

var x = user || {},
    y = x.name || {},
    z = y.first_name;
yzuktlbb

yzuktlbb5#

在Rails4中,try执行以下操作:
调用其名称作为第一个参数的公共方法,就像public_send一样,不同之处在于,如果接收方不响应它,则调用将返回nil,而不是引发异常。
在Rails3中,try类似于Rails4中的try!,并且与try相同,只是如果对象不理解你试图调用的方法,它会发出抱怨。try的最初意图是隐藏一系列nil检查,这样你就可以说:

o.try(:m)

而不是

o.nil?? nil : o.m

Rails4版本还隐藏了一个检查,检查对象是否理解您要调用的方法。
在JavaScript中没有特殊的语法,但是可以将这些丑陋的东西放到一个函数中。
Rails 4版本的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;
}

如果obj不理解method_name(包括objnull还是undefined),你会说x = rtry(obj, 'method_name', arg1, arg2, ...)xnull
演示: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'。尽管如此,主要用途(即隐藏nullundefined检查)应该在任何地方都有效。

hyrbngr7

hyrbngr76#

我不这么认为。为什么不自己卷?不完全等同,但做的工作。

function tryMe(obj) {
  return obj === null || obj === undefined ? null : obj;
}

相关问题