给出严格相等参数的纯函数产生非严格相等的结果
Pure function given strictly equal arguments yielding non-strictly equal results
下面是一个纯函数f
,尽管a === b
(注意严格的等式)对a
和b
的某些值f(a) !== f(b)
:
var f = function (x) {
return 1 / x;
}
+0 === -0 // true
f(+0) === f(-0) // false
这些函数的存在会导致难以发现的bug。还有其他我应该厌倦的例子吗?
是的,因为NaN !== NaN
.
var f = function (x) { return Infinity - x; }
Infinity === Infinity // true
f(Infinity) === f(Infinity) // false
f(Infinity) // NaN
其他产生NaN
的例子,其参数可以严格相等:
0/0
Infinity/Infinity
Infinity*0
Math.sqrt(-1)
Math.log(-1)
Math.asin(-2)
这种行为是完全可以的,因为在数学理论中,-0 === +0
是正确的,而1/(-0) === 1/(+0)
不是,因为-inf != +inf
编辑:虽然我真的很惊讶javascript实际上可以处理这些数学概念。
EDIT2:另外,你所描述的现象完全是基于这样一个事实,你除以零,你应该期待至少一些奇怪的行为。
1/+0
为Infinity, 1/-0
为-Infinity,而+0 === -0。
这可以通过以下事实来解释:ECMA将-0定义为特殊情况下等于+0,而在其他操作中,这两个值保留其不同的属性,从而导致一些不一致。
这是唯一可能的,因为语言显式地将两个不相等的值定义为相等,而实际上不是。
其他的例子,如果有的话,应该基于同样的人为平等,并且给出http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.6,没有其他这样的例外,所以可能没有其他的例子。
如果它有任何用处,我们可以通过添加0
来确保0
不是-0
:
var f = function(x) {
return 1 / (x + 0);
}
f(+0) === f(-0)
在ECMAScript 3中,另一个===
行为令人惊讶的例子是与连接的函数。考虑这样一个情况:
function createConstantFunction(result) {
return function () {
return result;
};
}
var oneReturner = createConstantFunction(1); // a function that always returns 1
var twoReturner = createConstantFunction(2); // a function that always returns 2
允许实现"连接"两个函数(参见规范的13.2节),如果这样做,那么oneReturner === twoReturner
将是true
(参见13.1.2节),即使这两个函数做不同的事情。类似地:
// a perfect forwarder: returns a sort of "duplicate" of its argument
function duplicateFunction(f) {
return function (f) {
return f.apply(this, arguments);
};
}
var myAlert = duplicateFunction(alert);
console.myLog = duplicateFunction(console.log);
这里的实现可以说是myAlert === console.myLog
,尽管myAlert
实际上相当于alert
, console.myLog
实际上相当于console.log
。
(然而,ECMAScript 3的这方面在ECMAScript 5中没有保留:函数不再被允许连接)
我不太确定这是所以可怕;-)Javascript不是一种纯粹的语言,+/-0的存在以及-0和+0的相等性是特定于IEEE-754的,并且是"定义良好的",即使有时可能令人惊讶。(例如,即使NaN != NaN总是为真也是定义良好的。)
From signed 0:
根据IEEE 754标准,负零和正零应该用通常的(数值)比较运算符进行相等的比较…
从技术上讲,由于f
的两个输入不同,那么结果也可能不同。无论如何,Haskell会将0 == -0
视为真值,而将(1 / 0) == (1 / (-0))
视为假值。
然而,我确实发现这是一个有趣的问题。
快乐编码。
有很多这样的函数,下面是另一个例子
function f (a) {
return a + 1;
}
1 == "1"但是f(1) != f("1")
这是因为平等是一个微妙的概念。
也许更可怕的是在你的例子中-0 === +0。
- jquery jqgrid 不显示结果,具体取决于 JSON 对象中的参数
- 使用Javascript从DB中筛选结果,这将使DIV重新加载它'基于新参数的内容
- JS:通过键访问参数时出现奇怪的结果
- 如何从批处理文件调用一个带有2个参数的java脚本函数,并将结果返回到环境变量
- 如何使用URL参数筛选表中的结果
- 具有意外结果的 Javascript 函数参数
- JavaScript unshift 参数返回意外结果
- 文件读取器加载与结果和参数
- 将参数传递给 javascript 中的结果处理程序函数
- 传递g:remoteLink中的参数作为javascript函数的结果
- 如何在函数参数中使用循环并将结果记录到控制台
- Javascript在评估所有参数之前返回结果
- 如果使用参数数组调用,则日期会更改结果
- 如何通过参数获取Chrome本地存储结果的值映射
- 当使用类似的参数调用日期构造函数时,会提供意外的结果
- Angular JS发送参数并返回结果
- 如何在每个表行上放置click事件,并将结果作为参数传递,以将新数据绑定到另一个源
- Mongo:使用$in数组参数对结果进行排序
- .call()函数将函数作为参数而不是结果传递
- jQuery:如何在事件发生之前执行代码,并在事件时将结果作为参数