<你不知道的Javascript>笔记
来源:互联网 发布:淘宝仿真金属狙击枪 编辑:程序博客网 时间:2024/06/05 17:41
前言
Javascript本身是一门非常灵活的语言,如果是先有写过编译型语言的再来看看它,简直是灵活到你可以接近”瞎写”的程度还不会出错.
然而凡事皆有双面性,它的灵活性背后是无数的坑.Javascript设计的时候,估计也没有考虑到会发展成今天这个规模,更是没有想到它居然可以用在后端.
很多在前端设计中无所谓的坑,放在后端就是灾难.这本书非常详细的介绍了那些Javascript中看似古怪的设计及其背后的深层次原因,值得一读.
这份笔记里将记录一些我认为比较有实践意义的东西.对于那些实际代码中应该抛弃的奇怪写法,不做深究.
类型转换
js本身规定了六个基本类型,在必要的时候,会发生类型转换.
let a = 42;let b = a + ""; let c = String(a);
第二和第三个赋值操作时,都发生了类型转换,前者是隐式,将a强制转换为string类型,后者是显式.
转为string
基础类型转化规则定义如下:
* null: “null”
* undefined: “undefined”
* boolean: “true”/”false”
* number: 通常和常规数学表达一致.有个特殊情况,在数字很小或很大的时候,将会转换出指数形式的结果,比如”1.07e21”
JSON.stringify()
所有JSON安全的值都可以用这个方法转为字符串.以下情形不属于JSON安全的对象:undefined, function, symbol
以及循环引用.遇到前三者时会自动忽略,而循环引用会报错.
以下代码可以创建一个具有循环引用的JSON对象:
let a = {"prop0": "safe"};a.prop1 = a;
JSON.stringify()还具有一个可选的参数,叫做replacer
.这个参数可以传两种类型的值进去,数组和函数.
* 传入数组的时候,这个数组里元素必须是字符串.它指出了JSON对象中要处理的键.未在该数组中列出的键会被忽略.如:
let a = { "b": 0, "c": 1, "d": 2};JSON.stringify(a, ["c", "d"]);
- 传入函数的时候,对象的每个键会调用一次,同时对象本身也会调用一次.
转为number
true转换为1,false转换为0(反过来好像也是这样).undefined转换为NaN,null转换为0.
转为boolean
ES5中定义了转换为boolean类型时的规则.转换结果为false的如下:
* undefined
* null
* false
* +0 -0 NaN
* ""
除此以外,其它所有的东西,转换结果都是true.包括空对象,空数组这些.
显式转换
string & number
字符串转数字,如果要用类型转换的方式来做,如下:
let c = "3.14";let d = 5+ +c;
这其实是一种可读性很差的写法,我个人并不推荐这么写.书里还举了一个疯狂的例子:
1 + - + + + - + 1; // What the fuck?
还可以调用构造函数Number()
进行转换.
另外,用的比较多的parseInt()
也是一个办法,不过它的准确定义应该是解析字符串,而非类型转换.parseInt()
函数还有第二个参数,指定了转换数字的目标进制.比如要字符串是十六进制表示,如下:
let a = "100";parseInt(a, 16);
注意,这里是将100作为一个十六进制数来看待,而并不是将100作为一个十进制数看待,返回转十六进制的结果.
与之相反的,是toString()
方法,它也可以附带一个参数,将Number
类型的数据转成字符串并以指定的进制输出.一个有趣的应用是产生随机字符串:
(Math.random()*100000000000).toString(36).replace('.', "");
这段代码的原理就是36进制的表示恰好是0-9和a-z的完整集合,转成字符串之后,字符串里只会包含数字和小写字母.
| 和 ~运算符
~运算符会对一个32位有符号整数执行按位取反操作,包括符号位.如果目标参数不是整数,则先强制转换为整数,再执行取反.
|会对一个32位有符号整数执行按位或操作.如果参数不是整数,同样转换为整数再运算.
如下两个应用会实现取整的效果:
let a = 1.123;let b = 0 | a;
由于0和任何数按位或都是另一个数本身,因此这里返回的就是a取整的结果.
let a = 1.1415926;let b = ~~a;
第一个~首先将a取整后取反.a取整的结果是0x00000001
,按位取反后是0xfffffffe
,即-2的补码表示.第二个~对0xfffffffe
进行按位取反,就得到了取整的结果0x00000001
.
这种写法看似简洁,并且使用了位运算.一个通常的说法是使用位运算效率会高很多.对于编译型语言,结论成立.对于解释型语言,打问号.看如下的代码:
let a = [];for (let i = 0; i < 100000; i ++) { a.push(Math.random() * 1000000)}let ts = Date.now();for (let i = 0; i < 100000; i ++) { ~~a[i];}console.log(Date.now() - ts);ts = Date.now();for (let i = 0; i < 100000; i ++) { Math.floor(a[i]);}console.log(Date.now() - ts);
在我的机器上跑下来的结果是,前者26ms,后者3ms.当然,这个结果会随着不同的node版本会有差异,但已经足够证明一点:不要迷信那些在传统编译型语言中惯用的优化手段.
- 你不知道的JavaScript(上卷)笔记
- <你不知道的Javascript>笔记
- 你不知道的 Javascript
- 你不知道的 Javascript
- 你不知道的JavaScript笔记之关于this
- 你不知道的JavaScript学习笔记1
- 你不知道的Javascript笔记:up & going
- 你不知道的javaScript【笔记】--- LHS与RHS
- 《你不知道的javascript》阅读笔记(上卷第一部分)
- 你不知道javascript
- JavaScript--你不知道你不知道
- [图解] 你不知道的 JavaScript - “this”
- [图解] 你不知道的 JavaScript - “this”
- 【图解】你不知道的 javascript “this”
- Javascript 你不知道的事
- 你不知道的JavaScript--Item5 全局变量
- 你或许不知道的javascript细节
- 你不知道的JavaScript细节整理
- 【Linux】在Linux上安装VNC
- tornado + django + nginx + mysql网站源码分享
- 时域分析的matlab实现
- 编译Hadoop 2.9.0 提示 Could not find artifact com.amazonaws:DynamoDBLocal
- Java NIO 通道
- <你不知道的Javascript>笔记
- IT的道德与伦理
- PMP笔记-项目质量管理的重点和难点
- 戏说系列-从术和道来看基于流量的架构设计(上)
- okex 早日关闭
- 多类别SVM损失和交叉熵损失比较
- 聚宝川之行
- 机器学习实例之PCA(主成分分析)
- Leetcode代码学习周记——Hamming Distance