JavaScript 进阶(五)易混淆概念null vs undefined, == vs ===, string vs String
先看一段代码
- var foo = {}
- foo.a = null
- alert(foo.a == null) //true
- alert(foo.a === undefined) //false
- alert(foo.b == null) //true
- alert(foo.b === null) //false
直观上来看,foo.a 是 null, foo.b 是undefined,所以null == undefined 为true,null === undefined 为false。null与undefined似乎都代表空,== 与 === 都代表相等判断,那么JavaScript为什么要引入这两对相似的概念,它们又有什么区别呢?我们往下看。
null 与 undefined
== 与 ===
- false == 0
- true != 2
- 1 == "1"
- true != "true"
- true == "1"
2. 对于对象(数组也是对象,String不是)
- var a = {}
- var b = a
- a == b, a === b;
- {} != {}
3. 如果是一方是对象,一方是基本数据类型呢?
- "abc" !== new String("abc")
- "abc" == new String("abc")
- 1 == new String("1") // 坑爹的string和String,下文会详细的讲“字符串”
- var a = {}
- a == "[object Object]"
- a.toString = function(){return "1";}
- a == 1
坑爹的String和string
- var a = "abc";
- typeof(a) == "string"
- var b = new String("abc")
- typeof(b) == "object"
- a == b //参考上一段的规则3,b.toString() == "abc"
- //之前一直认为a, b 都是对象, 并且类型相同,都是那个“string”,直到我今天为了写博文,测试了如下代码:
- var s1 = new String("abc");
- var s2 = new String("abc");
- s1 != s2 //what a fuck
- //其中==是比较两个string的内容,事实上 s1 != s2,所以我就纳闷了。事实上他们俩都是object,适用于上一篇的规则2.
所以代码中直接用双引号产生的string和new String出来的东西还是有点区别的。
有什么用?
我没预期过学这些东西能在我生活中起些什么实际作用,不过十年后,当我在设计第一台麦金塔(Macintosh)时,我想起了当时所学的东西,所以把这些东西都设计进了Mac里,那是第一台使用了漂亮印刷字体的电脑。如果我当时没有退学,就不会有机会去参加这个我感兴趣的美术字课程,Mac就不会有这么多丰富的字体,以及赏心悦目的字体间距。因为Windows照抄了Mac,所以现在个人电脑才能有这么美妙的字型。
上面是鸡汤啊,看起来没啥料,下面加点私货,说说我对编程中的一些所谓“冷门知识”的观点:
1. 函数重载。 比如一个库函数foo(a, b). 当调用方调用foo(a)的时候,foo函数内部的b就是undefined。在foo函数内部,检查参数是否===undefined来确定调用方到底是foo(a) 还是foo(a, null).
2. 断言。开发阶段使用断言能够让代码在出错点立刻崩溃,防止错误蔓延,从而提高调试效率。在使用断言时,要确保值和类型都正确无误,所以要使用===。3. 到底是返回null还是undefined? 对于数值计算,如果计算参数不合适,要么抛出异常,要么返回null或0作为空值。避免返回undefined,这样做会导致它的上层算式变成NaN,可能会导致错误蔓延。对于需要返回string的地方,如果出错,则要么抛出异常,要么返回空串,避免返回null或是undefined,否则就会出现“null”, "undefined"的字符串。如果应该返回对象,则应该返回null,而避免返回undefined。null和对象类型相同,防止在需要判断变量类型的地方由于一个“undefined”导致控制逻辑跑到不该去的地方。然而对于一个没有返回值的过程,则应该明确的返回undefined或是直接写return或者干脆不写return语句。4. 如果你需要判断一个对象是否拥有某一个属性,则应该使用hasOwnProperty函数。这个函数无论该属性是null还是undefined,只要属性存在,则都返回true。此外,如果你需要明确的删除一个属性,则使用delete,而不要仅仅将其置null,undefined。null,undefined不仅仅会被hasOwnProperty返回true,同时这个属性仍然是可枚举的,就是用 for - in 来遍历对象的时候仍然能够被遍历出来。5. 修改String的prototype。比如我们的代码中经常需要反转一个字符串,那么每次都这样调用reverse(s1)。这样则需要在全局名空间定义一个reverse函数。然后可以通过修改prototype来给所有的String对象提供该函数。String.prototype.reverse() = function(){}. 当这么做以后,无论是new String还是 “”字符串常量,均可以使用"abc".reverse()来返回一个反转后的字符串。6. 编写代码的时候尽量依赖内容判断而非类型。因为 == 和 === 都判断相等,。null 和 undefined都代表”无“,在阅读代码的时候很容易就直接在逻辑层面就认为它们等价了。在一段逻辑中,如果是处理数字,那么推荐在逻辑入口处将所有的入参转为数字,那么逻辑内部就不会因为== 和 ===问题出错,字符串也类似。在判断值是否为空时,尽量让分支逻辑不依赖null还是undefined。如果你的代码中typeof比较多而散布的时候,就要重新考虑一下设计的问题了。让业务逻辑层面关注内容,至于typeof,==/===, null/undefined的处理,尽量集中地放在底层库,并且由资深程序员处理。
JavaScript 进阶(五)易混淆概念null vs undefined, == vs ===, string vs String的更多相关文章
- 【C#小知识】C#中一些易混淆概念总结(五)---------继承 分类: C# 2014-02-06 22:05 1106人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- 【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- C#中一些易混淆概念总结
C#中一些易混淆概念 这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框 ...
- 【C#小知识】C#中一些易混淆概念总结(七)---------解析抽象类,抽象方法
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...
- 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) [C#小知识]C#中一些易混淆概念总结(三) ------------------------------ ...
- 【C#小知识】C#中一些易混淆概念总结(三)---------结构,GC,静态成员,静态类
目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) ---------------------------------------分割线----------- ...
- 【C#小知识】C#中一些易混淆概念总结---------数据类型存储,方法调用,out和ref参数的使用
这几天一直在复习C#基础知识,过程中也发现了自己以前理解不清楚和混淆的概念.现在给大家分享出来我的笔记: 一,.NET平台的重要组成部分都是有哪些 1)FCL (所谓的.NET框架类库) 这些类是微软 ...
随机推荐
- sc delete 服务名
当我们在cmd里使用 sc delete 服务名 ,来删除服务的时候,报错误,SC OpenService 失败5:拒绝访问. 这似乎是因为权限不够,解决方法. 首先,我们必须先取得管理员权限,以 ...
- MYSQLI - mysqli
PHP MysqlI操作数据库 1连接数据库. //procedural style$mysqli = mysqli_connect('host','username','password','da ...
- unity学习中经常要碰到的几种数据结构
常碰到的几种数据结构:1.Array,2.ArrayList,3.List<T>,4.LinkedList<T>,5.Queue<T>,6.Stack<T&g ...
- BZOJ AC300题留念
- android:music
package com.terry; import java.io.File; import java.io.FileFilter; import java.io.IOException; impor ...
- modelsim中的文件操作—— 大数据测试
在modelsim中不可避免的需要进行文件操作,在窗口中查看代码的操作情况,下面是我自己M序列实验中的一段测试代码 integer i,j ,k,m; integer m_dataFILE , ind ...
- 基于visual Studio2013解决C语言竞赛题之0502最小数替换
题目
- 0-1背包的动态规划算法,部分背包的贪心算法和DP算法------算法导论
一.问题描述 0-1背包问题,部分背包问题.分别实现0-1背包的DP算法,部分背包的贪心算法和DP算法. 二.算法原理 (1)0-1背包的DP算法 0-1背包问题:有n件物品和一个容量为W的背包.第i ...
- Codeforces 331A2 - Oh Sweet Beaverette (70 points)
贪心搞就行,用map记录每个数出现的下标,每次都取首尾两个.将中间权值为负的删掉后取sum值最大的就行. #include<iostream> #include<algorithm& ...
- BON取代半岛电视,美国人要“换口味”了吗?
记得很久以前唐骏在某高校演讲时,讲了这么一个笑话,他问一位美国最普通的大妈,“请你说出三个印象最深刻的中国城市”,在北京奥运会之前,这位大妈说了如下三个城市:北京.香港.新加坡.很显然,这位大 ...