首先介绍一下上下文(如果您更愿意关注代码,可以跳过此部分。)
我加入了一个新项目,该项目将集成在 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等库。
答案 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;
如果val
或undefined
为null
/ 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));
或if
为false
,则res
语句将返回res.metadata
,如果它们都存在,则会返回undefined
< em>仅当它被定义或res.metadata.status
时,否则它将返回0
。
答案 3 :(得分:0)
检查对象的属性时,检查与null
的松散相等是不够的。
松散相等(==
)在JavaScript中使用类型提示,它尝试将成员转换为通用类型,然后可以使用它来确定它们是否相等。
因此,JavaScript的最佳实践规定始终使用严格相等(===
),以便在检查值或类型时避免边缘情况或未知行为。
你可以在这里找到更多关于松散与严格平等的信息:
虽然这不是你职能中的必备条件,但遵循和养成习惯是一种好习惯,这样在以后的代码中可以避免松散平等(==
)的含义(例如当需要数字或字符串类型时,避免'3' == 3
。
虽然被某些人认为是该语言的缺点,但使用null
在意图上与检查undefined
类似,但实际上是要在代码中表示编码器期望{{1}提供(或缺少),而不是基本类型(object
,number
,string
,boolean
)。这与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);
}
最后一点,因为它清晰可见,遵循最佳实践确实增加了代码的大小,但好处是生成的代码更安全,抛出异常的机会更少(很多根)应用程序崩溃),更易于协作,并且更容易构建测试/覆盖。