javaScript 关于 == 那些事
2014-07-03 10:58
183 查看
本文所有代码都在
再定义一个函数来比对
输出结果:
这个结果大家基本上都能理解
结果为:
这个结果我们发现
和 0 比较
和空字符串比较
和false比较
这三种情况返回
这个结果让人不好理解
我们在valueOf方法中加入一些输出再来看看
输出结果为:
现在我们可以猜测一下了, javascript在进行对象和基本数据类型(暂且把string也当做一种基本数据类型,下面说基本数据类型的时候也会带上string)比较的时候,会调用对象的valueOf方法的返回值来进行比较.
这样就可以解释number比较中为什么和0比较是true了,
但是还有和空字符串比较是true,和false比较是true,这里我的理解是 javascript在数字和字符串以及boolean进行比较的时候,会转换成数字后进行比较,所以
只有最后一个和对象比较的时候没有打印
输出两次false
输出结果为:
这次和第一次比较没什么出入,只是打印了一些方法调用日志而已,结果也理所当然的应该这样了.
但是javascript为什么没有递归调用我们的
这次我们再加入一个toString方法来看看
输出结果为:
我们发现每次输出
也就是说 javascript在调用valueOf后发现不是基本数据类型的时候,会调用toString的返回值再来进行比较
和我们观测到的结果一致,只有
这样也可以解释为什么没有递归调用我们的
接下来我们再狠一点,
这次的结果会在意料之外的:
结果为:
结果报异常了
最后我觉得,javascript在将对象和基本数据类型进行比较的时候,会先调用
如果
node v0.10.28中测试通过,因为node用的也是v8的javascript引擎,所以理论上来说在chrome中的表现应该一致,其它引擎各位可以自己测试
准备工作
我们先定义一个对象来进行比较function foo() { this.name = "foo"; }
再定义一个函数来比对
function compare(f) { console.log("\ncompare with number:"); console.log("number f == 1: %s", f == 1); console.log("number f == 0: %s", f == 0); console.log("\ncompare with string:"); console.log("string f == \"\" : %s", f == ""); console.log("string f == \"foo\" : %s", f == "foo"); console.log("\ncompare with boolean:"); console.log("boolean f == true : %s", f == true); console.log("boolean f == false : %s", f == false); console.log("\ncompare with object:"); console.log("object f == {} : %s", f == {}); }
第一次比较
compare(new foo());
输出结果:
compare with number: number f == 1: false number f == 0: false compare with string: string f == "" : false string f == "foo" : false compare with boolean: boolean f == true : false boolean f == false : false compare with object: object f == {} : false
这个结果大家基本上都能理解
第二次比较
这次我们给这个对象添加一个方法valueOf然后再来进行比较看看
foo.prototype.valueOf = function() { return 0; };
compare(new foo());
结果为:
compare with number: number f == 1: false number f == 0: true compare with string: string f == "" : true string f == "foo" : false compare with boolean: boolean f == true : false boolean f == false : true compare with object: object f == {} : false
这个结果我们发现
和 0 比较
和空字符串比较
和false比较
这三种情况返回
true
这个结果让人不好理解
我们在valueOf方法中加入一些输出再来看看
foo.prototype.valueOf = function() { console.log('valueOf: '+ this.name); return 0; };
compare(new foo());
输出结果为:
compare with number: valueOf: foo number f == 1: false valueOf: foo number f == 0: true compare with string: valueOf: foo string f == "" : true valueOf: foo string f == "foo" : false compare with boolean: valueOf: foo boolean f == true : false valueOf: foo boolean f == false : true compare with object: object f == {} : false
现在我们可以猜测一下了, javascript在进行对象和基本数据类型(暂且把string也当做一种基本数据类型,下面说基本数据类型的时候也会带上string)比较的时候,会调用对象的valueOf方法的返回值来进行比较.
这样就可以解释number比较中为什么和0比较是true了,
但是还有和空字符串比较是true,和false比较是true,这里我的理解是 javascript在数字和字符串以及boolean进行比较的时候,会转换成数字后进行比较,所以
0 == ""和
0 == false也是true
只有最后一个和对象比较的时候没有打印
valueOf: foo所以也可以认为是对象比较时,只比较引用地址,理论上来说,对象比较 == 和 === 应该是一样的,例如如下代码:
var b1 = new Boolean(false); var b2 = new Boolean(false); console.log(b1 == b2); console.log(b1 === b2);
输出两次false
第三次比较
这次我们将valueOf方法再修改一下,返回不是基本数据类型试一下,就返回自己吧foo.prototype.valueOf = function() { console.log('valueOf: '+ this.name); return this; };
compare(new foo());
输出结果为:
compare with number: valueOf: foo number f == 1: false valueOf: foo number f == 0: false compare with string: valueOf: foo string f == "" : false valueOf: foo string f == "foo" : false compare with boolean: valueOf: foo boolean f == true : false valueOf: foo boolean f == false : false compare with object: object f == {} : false
这次和第一次比较没什么出入,只是打印了一些方法调用日志而已,结果也理所当然的应该这样了.
但是javascript为什么没有递归调用我们的
valueOf方法呢,按道理我们返回了自己,然后它进行比较的时候应该再次调用
valueOf的
这次我们再加入一个toString方法来看看
foo.prototype.toString = function(){ console.log(this.name + " : toString"); return this.name; }
compare(new foo());
输出结果为:
compare with number: valueOf: foo foo : toString number f == 1: false valueOf: foo foo : toString number f == 0: false compare with string: valueOf: foo foo : toString string f == "" : false valueOf: foo foo : toString string f == "foo" : true compare with boolean: valueOf: foo foo : toString boolean f == true : false valueOf: foo foo : toString boolean f == false : false compare with object: object f == {} : false
我们发现每次输出
valueOf的后面都跟随了一个
toString的调用.
也就是说 javascript在调用valueOf后发现不是基本数据类型的时候,会调用toString的返回值再来进行比较
和我们观测到的结果一致,只有
f== "foo"的结果是true
这样也可以解释为什么没有递归调用我们的
valueOf方法了
接下来我们再狠一点,
toString我们也返回自己,看看javascript会怎么处理
第四次比较
修改toString方法为:
foo.prototype.toString = function(){ console.log(this.name + " : toString"); return this; }
compare(new foo());
这次的结果会在意料之外的:
结果为:
console.log("number f == 1: %s", f == 1); ^ TypeError: Cannot convert object to primitive value at compare (/home/0x0001/Desktop/test.js:25:38) at Object.<anonymous> (/home/0x0001/Desktop/test.js:41:1) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3
结果报异常了
最后我觉得,javascript在将对象和基本数据类型进行比较的时候,会先调用
valueOf的返回值来进行比较,如果
valueOf返回的不是基本数据类型,那么继续调用
toString方法的返回值来进行比较,
如果
toString的返回值还不是基本数据类型,那么就无法比较了
相关文章推荐
- 关于Javascript 那些事
- JavaScript中,关于new的那些事
- 【web开发】关于Javascript事件注册的那些事
- 关于JavaScript继承的那些事
- 关于JavaScript那些事
- 关于javascript基础那些事。。。
- 关于JavaScript限制字数的输入框的那些事
- (原创)关于Javascript的应用技巧
- 关于javascript的两个重要的应用
- javascript写的关于静态页面获取URL传递参数的函数[原创]
- 关于WEB交互式设计,JavaScript以及AJAX的一点心得
- 关于javascript中parseInt函数的一个所谓的bug
- 关于在vs2003下对脚本程序的调试 如 :javascript
- 关于vbscript 与 javascript如何传递变量(包括服务器端与客户端)
- [收藏]Javascript关于日期的各种技巧和方法总结[欢迎补充]
- 关于javascript的小东东
- javascript 关于表单的一些validation
- [Javascript]关于在ASP.NET环境中调用梅花雨的日历控件出错的解决办法
- JavaScript 关于动态添加表格行问题
- javascript写的关于静态页面获取URL传递参数的函数[原创]