当我注意到这个有趣的细节时,我正在玩Google Apps脚本API,如下面的代码所述
function testEmptyRange() {
var range = SpreadsheetApp.getActive().getSheetByName("Sheet1").getDataRange();
var values = range.getValues();
Logger.log(values.length + " " + values[0].length);
Logger.log((values[0][0] == "") + " " + typeof values[0][0]);
Logger.log((values[0] == "") + " " + typeof values[0]);
Logger.log((values == "") + " " + typeof values);
}
如果Sheet1
没有任何内容,则values
是1-by-1 2D array of Objects,实际上是包含空字符串的单个单元格。令我感到惊讶的是 values
和 values[0]
,类型object
,也等于空串。上述函数生成的日志是
[17-03-05 00:43:46:807 EST] 1 1
[17-03-05 00:43:46:807 EST] true string
[17-03-05 00:43:46:808 EST] true object
[17-03-05 00:43:46:808 EST] true object
我想解释一下为什么会这样。对象如何等于空字符串?我意识到运算符==
与运算符===
不同,如果我要用后者替换前者,那么false
的日志显示values
和values[0]
,这更符合预期的行为,我想。但这并不能解释为什么或如何在第一种情况下对象可以等于空字符串,我想了解这里发生了什么。
答案 0 :(得分:3)
正如您所提到的,问题是==
并不代表最严格的比较。 ==
使用其参数的类型强制来尝试对我们的程序员更有帮助。
当==
的一个参数是string类型时,另一个总是在比较两个值之前转换为字符串。因此,对于一个对象,JavaScript引擎最终会做这样的事情:
object == ""
String(object) === ""
object.toString() === ""
由于对象可以使用任何toString
方法,因此此比较的输出可能为true
。
修改:查看上面anied的评论并重新阅读您的示例代码,我发现values
和values[0]
实际上是 arrays ,这是对象类型的特例。他们有一个toString
方法,用逗号连接所有数组元素,这意味着空数组[]
将被字符串化为""
var object = {
toString: function () { return '' }
}
console.log(typeof object) //=> 'object'
console.log(object == "") //=> true
var array = []
console.log(typeof array) //=> 'object'
console.log(array == "") //=> true
var matrix = [
['']
]
console.log(typeof matrix) //=> 'object'
console.log(matrix == "") //=> true