你不知道的JS中册学习笔记
类型和语法啊
类型
-
七种内置类型
- null
- undefined
- boolean
- number
- string
- object
- symbol(ES6)
-
变量是没有类型的,只有值才有类型
值
- 数组中存取的键值如果是数字的话,将会被转换成索引值
var a = [];
a["2"] = 4;
console.log('a.length',a.length) // 3
如果采用键值赋值的方式,并不是按照顺序的存储
var a = [];
a["test"] = 4;
console.log("a["test"]", a["test"])
console.log('a.length', a.length)
// a["test"] 4
// a.length 0 ????为什么是这么个结果
-
字符串是不可变的,数组是可变的。
- 字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串
- 数组的成员函数是在其原始值上进行操作的
-
简单的字符串反转[不包括Unicode,星号,多字节字符]
var a = "test";
var c = a.split("").reverse().join("");
-
数字
- 由于二进制浮点数精度的问题 0.1 + 0.2 === 0.3 //false
(0.1+0.2实际等于0.300000000004) - 上述问题的常见解决方法是设置一个误差范围值(“机器精度”)–2^-52
- 由于二进制浮点数精度的问题 0.1 + 0.2 === 0.3 //false
-
void 没有返回值,因此返回结果是undefined(可以不让表达式返回任何结果)
-
NaN(not a number)是一个“警戒值”(sentinel value)仍然是数字类型,但是它和自身不相等,是唯一一个非自反的值
-
引用
- JS中引用指向的是值。在JS中变量不可能成为指向另一个变量的引用(区别与C++)
- JS对值和引用的赋值/传递在语法上没有区别,完全根据值的类型来决定。
var a = 2; var b = a; // b是a的一个副本 b++; a; // 2 b; // 3 var c = [1,2,3]; var d = c; // d是c的一个引用 d.push(4); console.log("c",c,"d",d); //c [ 1, 2, 3, 4 ] d [ 1, 2, 3, 4 ]
- 简单值总是通过值复制的方式来赋值/传递,包括null,undefined,字符串,数字,布尔,symbol
- 复合值–对象(包括数组和封装对象),函数。总是通过引用复制的方式来赋值/传递。
- 引用指向的是值本身而非变量,所以一个引用无法更改另一引用的指向
function foo(x){ x.push(4); console.log('x',x); x = [4,5,6] x.push(7); console.log('x',x); } var a = [1,2,3]; foo(a); console.log('a',a) // x [ 1, 2, 3, 4 ] // x [ 4, 5, 6, 7 ] // a [ 1, 2, 3, 4 ]
- 如果要更改上述a的为[4,5,6,7],必须更改x指向的数组,而不是为x赋值一个新数组。
function foo(x){ x.push(4); console.log('x',x); x.length = 0; // 清空数组 x.push(4,5,6,7); console.log('x',x); } var a = [1,2,3]; foo(a); console.log('a',a) // x [ 1, 2, 3, 4 ] // x [ 4, 5, 6, 7 ] // a [ 4, 5, 6, 7 ]
原生函数
-
常见原生函数
- String()
- Number()
- Boolean()
- Array()
- Object()
- Function()
- RegExp()
- Date()
- Error()
- Symbol()
-
原生函数可以被当作构造函数使用(创建出封装了基本类型值的封装对象)
-
浏览器已经为.length这样的常见情况做了性能优化,直接使用封装对象反而会降低执行效率
-
如果想得到封装对象中的基本类型值,可以使用valueOf()函数
var a = new String("abc");
a.valueOf(); // "abc"
-
Array
- 构造函数Array不要求带new关键字
- Array构造函数只带一个数字参数的时候,被设为数组长度,而不是数组元素。
-
RegExp
- 以常量形式(/^a*b+/g)来定义正则表达式,执行效率会更高,JS引擎会对他们进行预编译和缓存
- 动态正则表达式可用RegExp()
-
Date()和Errof()
- Date()[不加new] 与 getTime() 与 Date.now()即可得当前时间
- Error() 常与throw一起使用
-
Symbol()
- 不能使用new关键字
- 没有搞明白这东西到底是干嘛的
强制类型转换
语法
-
语句都有一个结果值
- statement completion value, undefined也算
- 控制台中输入var a = 2会得到结果值undefined
-
标签语句
- 下列语句中的contine foo 不是跳转到标签foo所在位置执行,而是执行foo循环的下一轮循环
foo:for(var i =0; i<4; i++){ for(var j=0; j<4; j++){ if(j == i){ continue foo; } if((j*i)%2 == 1){ continue; } console.log(i,j) }
}
//
1 0
2 0
2 1
3 0
3 2
```
-
代码块
[]+{}; // [object Object] {}+[]; // 0
-
运算符优先级
- && > ||
-
自动分号
- 自动分号插入
-
提前使用变量
- ES6中规范了一个新概念叫做TDZ(Temporal Dead Zone, 暂时性死区)
-
try throw ,finally ,catch
异步和性能
异步
- console环境实际是由宿主环境决定
- 事件循环
异步是现在和将来事件之间的间隙,并行意味着可以同时发生
回调
- 纸牌屋心理:它可以工作,但我不知道为什么,所以谁也别碰他
- 嵌套回调和链式回调
Promise
- 未来值
- 可能拒绝,也可能完成
生成器
- 生成器是一类特殊的函数,可以一次或多次启动和停止,不一定非要完成。