从节点应用程序

时间:2016-08-04 20:03:31

标签: javascript node.js null undefined lodash

首先介绍一下上下文(如果您更愿意关注代码,可以跳过此部分。)

我加入了一个新项目,该项目将集成在 nodeJS 的平台中。我们的团队确实拥有 JEE企业Web应用程序的经验。这奠定了我们的背景。这个新项目将使用REST API,聚合一些数据,实现一些业务逻辑并将这些数据传递给前端消费者。轻量级微服务架构。

一些同事开始研究该项目,我发现在源代码中我们有很多代码片段,如if (foo != null && foo.property != null) {return foo.property.value;}

Foo应该是作为参数传递给实现这种测试的函数的对象。

一个片段示例会说得更多。

让我们假装这是我正在消费的API的响应。我想写一个小函数,如果对象确实存在,将返回statusValue,如果它不是null或未定义,不是空的,并且属性确实存在,并且例如不是空白或空。

var response = {
  "services":[],
  "metadata": {
    "status": "statusValue"
  }
};

就像现在一样:

function getStatusValue(response) {
    if (response != null && response.metadata != null) {
        return response.metadata.status;
    }
};

什么被认为是实现它的最佳JS实践(我们也使用lodash所以也许这是使用lodash内部的更好的选择)。我只是担心我们会转换我们的Java习惯。

基本上我想知道如何安全地检查null, undefined, empty, blank(如果这是有道理的)。 2016年的JS最佳实践将是lodash和stuff等库。

4 个答案:

答案 0 :(得分:0)

使用Lodash,您可以使用_.isNil(response)记录的here函数。

一般来说,我会检查一个这样的变量:

if (typeof x !== 'undefined' && x !== null) {
  // x has some value
}

您应该检查x === undefined是否因为x 未定义,您将收到取消引用错误。

答案 1 :(得分:0)

这是一种(更简洁)的方式,只用JS做这样的事情:

var obj = ...;
var val = obj && obj.prop && obj.prop.val;
如果valundefinednull / obj,则{p> obj.prop将为obj.prop.val / &&;否则它将是||

这是因为null的短路评估。它的文字行为是这样的:如果第一个操作数是假的,它将计算到第一个操作数。否则,它评估为秒。这对布尔值的预期效果如预期,但正如您所看到的,它对于对象非常有用。

var val2 = val || "not found"; 有类似的行为。例如,您可以使用它来获取值,如果值为false,则使用默认值(例如"not found"):

val

请注意,如果0 任何虚假,包括""Option Explicit Sub RemovePunctuation() Dim cell As Range Dim calc as Long '## Get the original calculation state: calc = Application.Calculation Application.Calculation = xlCalculationManual With CreateObject("vbscript.regexp") .Pattern = "[^A-Za-z\ ]" .Global = True For Each cell In Worksheets("Raw").Range("A2:A1000").SpecialCells(xlCellTypeConstants) cell.Value = .Replace(cell.Value, vbNullString) Next cell End With For Each cell In Worksheets("Raw").Range("A2:A1000").SpecialCells(xlCellTypeConstants) cell.Value = LCase(cell.Value) Next cell '## Reset the calculation to original state Application.Calculation = calc End Sub ,这将评估为{{1}}。

答案 2 :(得分:0)

我会使用以下函数实现它:



extension UIViewController {

    public override static func initialize() {
        struct Static {
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            let originalSelector = #selector(UIViewController.viewWillTransitionToSize(_:withTransitionCoordinator:))
            let swizzledSelector = #selector(UIViewController.genericViewWillTransitionToSize(_:withTransitionCoordinator:))

            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)

            let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

            if didAddMethod {
                class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    }

    // MARK: - Method Swizzling
    func genericViewWillTransitionToSize(size:CGSize,
                                           withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator)
    {
        self.genericViewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
        coordinator.animateAlongsideTransition(nil, completion:
            {_ in
                UIView.setAnimationsEnabled(true)
        })
        UIView.setAnimationsEnabled(false)
    }
}




如果var response = { "services":[], "metadata": { "status": "statusValue" } }; function getStatusValue(res) { if (res && res.metadata) return res.metadata.status || 'not found'; else return 'not found'; } console.log(getStatusValue(response));iffalse,则res语句将返回res.metadata,如果它们都存在,则会返回undefined < em>仅当它被定义或res.metadata.status 时,否则它将返回0

答案 3 :(得分:0)

检查对象的属性时,检查与null的松散相等是不够的。

松散相等(==)在JavaScript中使用类型提示,它尝试将成员转换为通用类型,然后可以使用它来确定它们是否相等。 因此,JavaScript的最佳实践规定始终使用严格相等(===),以便在检查值或类型时避免边缘情况或未知行为。 你可以在这里找到更多关于松散与严格平等的信息:

虽然这不是你职能中的必备条件,但遵循和养成习惯是一种好习惯,这样在以后的代码中可以避免松散平等(==)的含义(例如当需要数字或字符串类型时,避免'3' == 3

虽然被某些人认为是该语言的缺点,但使用null在意图上与检查undefined类似,但实际上是要在代码中表示编码器期望{{1}提供(或缺少),而不是基本类型(objectnumberstringboolean)。这与Java或任何其他类型语言不同,其中function用于null类型定义的变量; 但是在JavaScript中没有约束给定类型的变量。

您可以在MDN上找到有关Object的更多详细信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

在实践中,特别是在处理来自单元之外的值时(这是任何API的情况)被认为是实际检查类型为null的最佳实践,以便制作确定具有属性。

虽然您的代码不正确,但它确实表明没有太多关注最佳实践,最终会导致编写错误的代码。

我对您的代码的建议,遵循最佳实践并且独立于任何库,是:

object

此外,从集成的任何库创建或使用它可能更容易,这是一个检查有效对象的函数;像_.isObject或者这样的东西:

function getStatusValue(response) {
        // must be of type `object`, to have properties.
    if (typeof response === 'object' &&
        // any variable of type `object` might be `null`, so exclude that.
        response !== null &&
        // `metadata` property must be of type `object`, to have properties.
        typeof response.metadata !== 'object' &&
        // `metadata` is of type `object`, check for not being `null`.
        response.metadata !== null) {


              // `status` property is expected to be a string, given by the API spec
          if (typeof response.metadata.status === 'string' &&
              // on strings, we can access the `length` property to check if empty string (0 chars).
              response.metadata.status.length > 0) {
                // all good, return `status` property.
                return response.metadata.status;
          } else {
            // `status` property is either not a string, or an empty string ('').
          }


    } else {
      // invalid `response` object.
    }
}

你可以在以后的剪辑中使用它,如下所示:

function isObject(o) {
  return (typeof o === 'object' && o !== null);
}

最后一点,因为它清晰可​​见,遵循最佳实践确实增加了代码的大小,但好处是生成的代码更安全,抛出异常的机会更少(很多根)应用程序崩溃),更易于协作,并且更容易构建测试/覆盖。