让我们看一下这段代码:
var token = (req.body && req.body.access_token) ||
(req.query && req.query.access_token) ||
req.headers['x-access-token'];
Taken from here.
这不应该返回一个 bool 值吗?最让我困惑的是链式 AND 和 OR 语句。我正在读这个:
The variable token equals the boolean whether req.body
AND req.body.access_token
exist. OR, if they don't exist, then it equals the boolean whether req.query
AND req.query.access_token
exist. OR, if they don't exist, it equals the value of req.headers['x-access-token']
.
此外,如果我们只分析这一 block :
var token = req.body && req.body.access_token;
是什么阻止了 token
被设置为 req.body
?
它并不是真正地评估 bool 表达式并将其分配给 token
。你所拥有的是一种简写 if-else
。让我们分解一下:
(req.body && req.body.access_token)
如果 req.body
是 "truthy" (在这种特殊情况下,它可能确保它不是 null
或 undefined
)然后它将分配 req.body.access_token
给 token
。表达式会在这里短路,不会继续进行。
否则,它会看下一个案例:
(req.query && req.query.access_token)
这个和上面一样;除了在这种情况下,如果 req.query
是“truthy”,它会将 req.query.access_token
分配给 token
。除非“falsy”,否则它也会在这里短路。
req.headers['x-access-token'];
这是最后的条款。如果上述情况都不成立,它将把 req.headers['x-access-token']
的值赋给 token
。
在传统形式中,它看起来像这样:
var token;
if(req.body && req.body.access_token) {
token = req.body.access_token;
} else if(req.query && req.query.access_token) {
token = req.query.access_token;
} else {
token = req.headers['x-access-token'];
}
What keeps the token from being set to req.body?
表达式为:
var token = req.body && req.body.access_token;
它不会将token
设置为req.body
。在这里,req.body
有点像一个标志。我们不想直接执行 req.body.access_token
因为 req.body
可能是 null
或 undefined
.所以它在这里做的是说“如果 req.body
是非空的/已定义,则将 req.body.access_token
分配给 token
” .请注意,如果 &&
的第一项为真,则仍必须评估第二项,因为只有当两个操作数都为真时,AND 才为真。然而,这里的优点是“评估”第二项也会返回该项的值,这就是最终设置为 token
的值。
更明确地说,上面的表达式可以表示为:
if(req.body !== null || typeof req.body !== "undefined") {
token = req.body.access_token;
}
但在 JavaScript 中,您可以简单地检查 if(some_var)
,如果 some_var
是,则不会运行 if
block 中的代码未定义
或 null
。但是您必须小心,因为像 0
或空字符串这样的合法值是“虚假的”,您最终可能会忽略它们。