《你不知道的JavaScript》是一个不错的JavaScript系列书,书名可能有些标题党的意思,但实符其名,很多地方会让你有耳目一新的感觉。

1.typeof null === "object"// true

ES6中JavaScript的类型有:null、undefined、string、number、boolean、object和symbol。但为啥上面的表达式为true呢?这其实是JavaScript的一个bug。最初设计是根据类型对应的前三位是不是0来判断是否为一个object。而null全部为0,所以null的类型误判为object。要准确判断null需要这样:

var a = null;
(!a && typeof a === "object"); // true

因为null本身是一个假值("",undefined,false,0)。而像function,{},Array等都属于object。

2.undefined与未申明

而对于未赋值的变量,type of 返回undefined,未申明的变量也返回undefined,虽然这有点迷惑,但用以检测一个变量会比较安全:

直接操作一个未申明的变量会报错,所以下面这样检测比较好:

if(typeof a !=="undefined"){}

等同于:

if(window.a){}

通过window的全局属性去检测,看起来更简洁,但是要注意场景,前提是存在window,且a为全局变量。

3.数字的语法

1)JavaScript中数字前面的0可以省略,小数后面的0也可以省略

且toFixed方法本身带有四舍五入的效果。

实际上可能不会有人这么写,直接对一个数字进行小数处理。但让我们认识到,对于数字而言,‘.’被视为常量12的一部分,所以上面的错误就相当于没有属性访问运算符'.'来调用toFixed方法。

以上三种是可以的,以区分'.'是属性访问器还是常量的一部分。

2)最小数

这个错误大家应该都知道,JavaScript中的浮点数并不是十分精确。所以0.1+0.2的结果并非刚好等于0.3。再比如我的ofo账单中

所以在JavaScript中判断浮点数需要带上一个精度范围。

if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
};
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
numbersCloseEnoughToEqual(0.1+0.2,0.3) //true

3)最大数

我们对一个字符串进行转换,parseFloat和parseInt都只能到16位。其他的后面全部补0了。这个要注意了,让前端传给的id啊,唯一号啊都应该是字符串的,当然这在调用api的时候没有问题,因为都是字符串。但有一次我遇到这个坑是因为ProtoBuf的自定义协议中别人定义了个19位的int。结果就拿不到数据了。

4.void 运算符

void不改变表达式的结果,只让表达式不返回值。我们可以使用void 0来获得undefined。void 1、void true和undefined之间并没有实质的区别。

其实每个表达式都有返回值,我们在console中操作的时候就会发现。第三个undefined是void的作用。 像赋值表达式,定义表达式的返回值无法运用。

特殊一点的比如setTimeout这个方法,每次调用都会返回一个数字,这个数字其实是计数器的一个唯一标识符,用来让你取消的。你可以用 void抹掉,但这简直是给自己挖坑。

5.不是数字的数字

NaN是个很奇葩的对象,自己不等于自己。

typeof NaN==='number'//true

但它确实属于number。

虽然window自带isNaN方法,但这个方法有bug。居然判断字符也返回true。但可以用到它的奇葩特性来判断NaN。它是唯一一个自己不等于自己的值。

if (!Number.isNaN) {
Number.isNaN = function(n) {
return n !== n;
};
} Number.isNaN(b)

6.奇特的~运算符

位操作符(|和~)和某些特殊数字一起使用时会产生类似强类型转换的效果,返回另外一个数字。

0|undefined//
0|NaN//
0|Infinity //

你可能想到了用来代替parseInt。but,只有10位。

超过11位成了有符号的整数。用乘法相当于parsInt,16位是正确的。超过了就说不好了。

~ 非操作符,在JavaScript中的效果就是值的负数减一。

这个特性可以配合indexOf一起使用:

var a = "Hello World";
if (~a.indexOf( "lo" )) { // true
// 找到匹配!
}
if (!~a.indexOf( "ol" )) { // true
// 没有找到匹配!
}
if (a.indexOf( "lo" ) >= 0) { // true
// 找到匹配!
}
if (a.indexOf( "lo" ) != -1) { // true
// 找到匹配!
}
if (a.indexOf( "ol" ) < 0) { // true
// 没有找到匹配!
}
if (a.indexOf( "ol" ) == -1) { // true
// 没有找到匹配!
}

上面两种比起下面的4种要简洁一些。当然你可能一开始不习惯,这到底是匹配了还是没匹配。记住-1取反为0,0为false。

7.假值的相等比较

==会进行隐式的强制类型转换

"0" == null; // false
"0" == undefined; // false
"0" == false; // true -- 晕!
"0" == NaN; // false
"0" == 0; // true
"0" == ""; // false
false == null; // false
false == undefined; // false
false == NaN; // false
false == 0; // true -- 晕!
false == ""; // true -- 晕!
false == []; // true -- 晕!
false == {}; // false
"" == null; // false
"" == undefined; // false
"" == NaN; // false
"" == 0; // true -- 晕!
"" == []; // true -- 晕!
"" == {}; // false
0 == null; // false
0 == undefined; // false
0 == NaN; // false
0 == []; // true -- 晕!
0 == {}; // false

这个结果真让人大跌眼镜。{}和[]其实是为真的。

更夸张的是:

所以 false==[] 很让人迷惑,背后是因为都转成了0==0。所以最好是使用===来避免不经意的强制类型转换。

8.运算符优先级

&&与||是比较熟悉的。a&&b,如果a为真,则返回b。a||b,如果a为真返回a,否则返回b。

&&可以用来代替单个if。

a&&foo();

如果a为真就执行foo(),如果要执行多个语句,可以用括号括起来,中间用逗号分开。||可以用来处理默认值。

function foo(a){
a=a||1;
//....
}

&& 运算符的优先级高于 || ,而 || 的优先级又高于 ? : 。

a && b || c ? c || b ? a : c && b : a

相当于:

(a && b || c) ? (c || b) ? a : (c && b) : a

小结:以上是《中》的第一部分笔记。

【读书笔记】-- 你不知道的JavaScript的更多相关文章

  1. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  2. 【 js 基础 】【读书笔记】Javascript “继承”

    是时候写一写 “继承”了,为什么加引号,因为当你阅读完这篇文章,你会知道,说是 继承 其实是不准确的. 一.类1.传统的面向类的语言中的类:类/继承 描述了一种代码的组织结构形式.举个例子:“汽车”可 ...

  3. 【读书笔记】-- JavaScript模块

    在JavaScript编程中我们用的很多的一个场景就是写模块.可以看成一个简单的封装或者是一个类库的开始,有哪些形式呢,先来一个简单的模块. 简单模块 var foo = (function() { ...

  4. 读书笔记-你不知道的JS中-promise

    之前的笔记没保存没掉了,好气,重新写! 填坑-- 现在与将来 在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数. 程序中'将来'执行的部分并不一定在'现在'运 ...

  5. 读书笔记:JavaScript DOM 编程艺术(第二版)

    读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...

  6. 【读书笔记】-- JavaScript数组

    数组是一段线性分配的内存,它通过整数计算偏移并访问其中的元素.大多数的语言都会要求一个数组的元素是相同类型,但JavaScript数组可以包含任意类型. var misc = ['string', n ...

  7. 【读书笔记】javascript 继承

    在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. func ...

  8. 读书笔记:javascript高级技巧(二)

    四.惰性载入函数 因为浏览器兼容的原因,我们的javascript代码会有大量的if语句,将执行引导到正确的代码中,看如下函数: function createXHR(){ if (typeof XM ...

  9. 读书笔记:javascript高级技巧(一)

    一.安全的类型检测 javascript内置的类型检测机制并非完全可靠,由于浏览器或者作用域等原因,经常会发生错误.大家知道,在任何值调用toString()方法都会返回一个[object Nativ ...

  10. 读书笔记之 - javascript 设计模式 - 接口、封装和链式调用

    javascript 采用设计模式主要有下面的三方面原因: 可维护性:设计模式有助于降低模块之间的耦合程度.这使代码进行重构和换用不同的模块变得容易,也使程序员在大型项目中合作变得容易. 沟通:设计模 ...

随机推荐

  1. udp 双机通信(服务器循环检测)2

    此文摘自:http://blog.csdn.net/qinpeng100423/article/details/8980423,谢谢了 自己上一篇写的udp通信,只能运行一次,参考了这位博主的,只是把 ...

  2. C语言的函数类型

    C语言的函数类型与返回值类型不一致时出现,是以函数类型为标准; 而如果在java与c#语言中上述情况是编译错误的;

  3. Android系统之灯光系统--通知灯深入分析

    Android通知灯的深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 getSystemService(通知服务) 构造notification 类别 其他参数(颜色,onMS,of ...

  4. C# XmlSerializer将对象序列化以及反序列化(Sqlite数据库)

    获取不同数据库表信息将筛选出来的信息序列化以及反序列化 相应类结构: Class Tables: [Serializable] [XmlRoot("Table")] public ...

  5. Top命名的一些简单用法

    1. Top命令的显示 top 2. 按(Shift + O)是为了选择列进行排序.例如:按a是为了通过PID进行排序.然后按任意键返回主窗口. 3. 显示特定用户的进程. top -u hadoop ...

  6. Angular2的模块架构浅谈

    引言angular2相比1引入了更完善的模块系统,回忆ng1的应用中通常在页面的html标签或body标签中添加ng-app节点,值为应用的模块名,整个应用都将围绕这个模块来展开,到了ng2,模块概念 ...

  7. ubuntu12.04下安装pptp_vpn服务器

    1.下载安装apt-get install pptpd 2.配置/etc/pptpd.confvim /etc/pptpd.conf添加下面两行(在配置文件的最后取消注释修改IP即可)localip ...

  8. Top 10 Books For Advanced Level Java Developers

    Java is one of the most popular programming language nowadays. There are plenty of books for beginne ...

  9. VMware虚拟网络连接模式详解(NAT,Bridged,Host-only)

    序言 如果你使用VMware安装虚拟机,那么你必定会选择网络连接,那么vmware提供主要的3种网络连接方式,我们该如何抉择呢?他们有什么不同呢?这篇我们就做一个深入. 首先打开虚拟机设置里面的网络适 ...

  10. GDOI2015 解题报告

    首先嘛现在发现题目这么水我还啥都没想出来正是呵呵了.接下来就口胡下GDOI的题解吧 PS:代码什么的要请联系我 题目:快戳我 Day1: T1:这个嘛,可以先找到起点所能到达的每个点然后判断该点能否到 ...