类型和语法
- js 中变量是没有类型的,只有值有类型
- 类型判断方式:
- typeof:可以判断简单基本类型,返回小写字符串;除了 typeof function 返回 function 外,其余 object 类型都返回 object,null 因为语言 bug 也返回 object
- instanceof:可以判断类型是否存在于原型链的任何位置
- Object.prototype.toString.call():返回对象 [[class]] 属性,包含了对象类型
- undefined 和 undeclared
- js 的 undefined 和 undeclared 变量都会返回 undefined,使用未声明的变量会报 ReferenceError
- 使用 typeof 可以将一个未知的变量作为判断条件
- 0.1 + 0.2 不等于 0.3
- 因为 js 遵循的 IEEE754 规范,对浮点数的表示并不精确
- 解决方法:设置误差范围值,对 js 来说,这个值通常是 2^-52,在 ES6 中这个值被定义为 Number.EPSILON
//polyfill if(!Number.EPSILON){ return Math.power(2, -52) } else { return Number.EPSILON }
- null 和 undefined 的区别
- 二者都可以表示“空”的值或者“不是值” 的值
- undefined 表示没有值,或者说从未赋过值;是一个标识符,可以被当做变量使用和赋值;可以使用 void 运算符得到
- null 表示空值,指曾经赋过值,但是现在没有值;只是一个特殊关键字
- 强制类型转换
- ToString:
- 基本类型:null 转换为 “null”;undefined 转换为 “undefined”;true 转换为 “true”;数字位数不超过20位遵循通用规则,超过20位使用科学计数法表示;普通对象除非自定义了 toString() 方法,否则返回内部 [[ class ]] 属性
- JSON 字符串化:
- 不安全的 JSON:包含 undefined、function、symbol、循环引用的值或对象
- JSON.stringify():会首先调用 toJSON() 方法,所以可以通过自定义该方法来定义 JSON 格式;JSON.stringify() 可以传递一个数组或者函数作为参数,用来过滤数据;第三个参数为缩进符
- ToNumber:
- true 转换为 1,false 和 null 转换为 0,undefined 转换为 NaN;对象会先进行 ToPrimitive 操作,然后再对返回值进行强转
- ToPrimitive:
- 将对象转化为基本类型值,首先检查有没有 valueOf() 方法,假如有并且返回基本类型值,则调用 valueOf(),如果没有,则使用 toString() 的返回值
- a + “” 会调用 a 的 valueOf() 方法,然后将返回值转为字符串
- ToBoolean:
- undefined、null、""、false、+0、-0、NaN 返回 false,其它一般情况下返回 true
- 假值对象返回 false,比如已经废弃的 document.all(),返回包含所有 dom 元素的类数组对象,这个对象呢就是假值对象
- ToString:
- 显式类型转换:
- String()、Number()、Bollean()、!、+、-、|、~(适用于32位整数,相当于加一取反)
- parseInt():和 Number() 的区别是,传入参数是字符串,取值到非数值为止
- [] + {} = [object object]({} 被当做值)、{} + [] = 0({} 被当做独立代码块,所以相当于是 +[])
- && 和 ||
- 左边值为真的情况下,&& 会返回右边的值,|| 会返回左边的值
- == 和 ===
- ==:比较的时候,允许进行强制类型转换;数字和非数字进行比较的时候,非数字会先转化为数字;布尔值和非布尔值在比较的时候,布尔值会先转化为数字0或1;null == undefined;对象会先进行ToPrimitive 操作
- ===:比较的时候,不允许进行强制类型转换
- >= 和 <=:会直接对 < 和 > 的值进行取反
- 运算符优先级
- && 优先级大于 || 大于 =
- && 和 || 优先于 ? : 执行
- && 和 || 是左关联(执行类似于 (a&&b)&&c),而 ? : 是右关联(类似于 a ? b : (c ? d : e))
异步和性能
- 事件队列:一个 while(true) 循环,每一次循环称为 一个 tick
- 任务队列:在每一个 tick 后面的队列
- Promise:
- new Promise():构造函数,接受一个回调函数作为参数,返回一个 Promise
- then():接受一个或两个回调函数参数,返回一个 Promise
- catch():错误处理函数,接受一个回调函数参数,只处理 reject 或者错误,相当于 then(null, …),返回一个 Promise
- race():接受一个 Promise 数组,返回最先完成的 Promise 的 resolve 结果,最终返回一个 Promise;传入空数组会挂住
- all():接受一个 Promise 数组,只有所有 Promise 都完成,主 Promise 才会完成,假如有 Promise 返回 reject,则返回 reject 结果;传入空数组会立刻完成
- resolve():返回一个完成的 Promise
- reject():返回一个拒绝的 Promise
- Promise 局限性:
- 错误处理:Promise 链中的某个 Promise 出现错误,只能通过这个 Promise 的 then 来捕捉到,所以 Promise 链尾的最后一个 Promise 的错误永远捕捉不到
- 单一值:每个 Promise 只能返回一个值,所以假如有很多返回值的情况下,就必须将返回值包装为一个对象返回,假如在 Promise 链中需要使用返回值,就需要不断的进行拆封/封装操作(参数结构可以简化拆封操作),比较繁琐
- 无法取消 Promise
- 生成器
- yield:暂停位置
- generator.next(…):从 yield 的位置继续开始,可以传入相应值作为 yield 位置的替代值
- generator.value:yield 位置返回的值
function *add(x){ x++; x = yield x; return x } var a = add(5);//生成一个迭代器,所以可以通过 for...of 来迭代 yield 位置返回的值 a.next()//{ value: 5, done: false },第一个 next 是启动迭代器,yield 将函数分为两块,每块由一个next对应 a.next(10)//{ value: 10, done: true }
- 生成器使函数可以不用一次执行完成,可以在函数内部暂停执行