文档章节

javaScript 关于 == 那些事

0x0001
 0x0001
发布于 2014/07/03 10:58
字数 1305
阅读 886
收藏 33

本文所有代码都在 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的返回值还不是基本数据类型,那么就无法比较了

© 著作权归作者所有

0x0001

0x0001

粉丝 16
博文 4
码字总数 3146
作品 0
程序员
私信 提问
加载中

评论(2)

0x0001
0x0001 博主

引用来自“黄开源中国”的评论

建议读读javascript高级程序设计第三版。。。

谢谢,在看第四版,也就看到这两个地方,自己做了些测试
黄开源中国
黄开源中国
建议读读javascript高级程序设计第三版。。。
《javascript DOM编程艺术》读后

先把自己做的例子传上http://wjfdwr.svfree.net/ 话说,今年7月开始的实训,一直在做关于前台方面的事,当时听到要用javascript就在想,遭了完全不会啊,然后没办法,就只有一边学习,一边试...

jeffywon
2012/11/09
99
0
JavaScript 开发者必备:七大资源共享

【IT168 技术】JavaScript 最近几年已经由一个二流选手变成使用最广的函数式编程语言。越来越多的资源投入到这个语言的开发中。   我最近做了很多 JS 开发,有前台的,也有在后台使用 Node...

作者:itwriter
2012/03/19
0
0
JavaScript 开发者必备的7个资源

JavaScript 最近几年已经由一个二流选手变成使用最广的函数式编程语言。越来越多的资源投入到这个语言的开发中。 我最近做了很多JS开发,有前台的,也有在后台使用 Node.js 的。我想在这里分...

虫虫
2012/03/17
8.3K
5
WisdomPlanet-Javascript-Primer

WisdomPlanet-Javascript-Primer是一本Javascript入门方面的前端书,目前刚开始连载。书中以小说故事模式开展,讲解了JS的语言基础,作者希望通过此书让刚学编程或准备学习JS的同学作为一个学...

念念之间
2015/04/01
3
0
JavaScript 语言背后的公司 NPM 风雨飘摇:管理层出现变故

这个JavaScript包注册中心的裁员引发了关于社区成员命运的问题。 NPM, Inc是广泛使用的NPM JavaScript包注册中心背后的公司,代表“节点包管理器”(Node Package Manager)。在这家重要的小...

云头条
2019/04/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何创建spring-boot的web项目

第一步:新建一个maven项目 新建项目,选择maven 填写GroupId和ArtifactId 下一步默认即可,直接点击finish 创建完成后项目结构如下 第二步: 配置pom.xml 在pom.xml中添加如下代码: <p...

幻境fairy
19分钟前
46
0
「网易官方」极客战记(codecombat)攻略-地牢-Kithgard 斗殴-kithgard-brawl

每次你从一波波的敌人中存活下来,就会变得更难。但是你如果你输了,你必须要等一天后才能再次提交。 简介 这是一个无尽的挑战关卡,敌人会一波波地向你发起进攻,一次比一次强大,直到你坚持...

极客战记
21分钟前
68
0
基于数据回放功能开发的线性挂单流策略

前言 人们常说,交易是一门艺术,而艺术来源于灵感。所以今天想和大家分享一下,如何利用发明者量化数据回放功能,发掘自己的交易灵感。 交易的灵感和盘感 通常我们所说的灵感,是指人们在思...

发明者量化
26分钟前
40
0
技术答疑丨如何区分游戏短音乐与音效以及配音

在游戏的声音领域,一般游戏音乐、音效与配音,但是每个类别又有不同的细分,在我们奇亿音乐与游戏厂商的日常沟通中,发现这些问题一直困扰着大家,一起来看看吧。 1、如何区分游戏的音效与配...

奇亿音乐
27分钟前
66
0
如何在mac上录屏

新上手的苹果电脑,想要完成录屏操作还不知道从哪下手的小伙伴有福利了,小编今天分享如何在mac上录屏内容,需要的来一起了解吧~ 如何在mac上录屏 Aiseesoft Screen Recorder for Mac(录屏软...

麦克虾仔
39分钟前
48
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部