第一部分
第一章
1、
var a;
a; // undefined
b; // ReferenceError: b is not defined
undefined 和 is not defined 是两回事
2.
// 这样会抛出错误
if(DEBUG) {
console.log( "Debugger is starting" )
}
//这样是安全的
if (typeof DEBUG !== "undefined") {
console.log( "Debugging is starting" )
}
第二章
1.
var b = 42.; //42.这样的写法没问题,只是不常见,但从代码的可读性考虑,不建议这样写。
42.toFixed(3) 是无效语法,因为 . 被视为常量42.的一部分 , 42..toFixed(3) 则没问题
2.
Object.is() 主要是用来处理那些特殊的相等比较
Object.is(NaN, NaN) //true
Object.is(0, -0) //true
3.
对包含循环引用的对象执行JSON.stringify(..) 会出错
第4章
1.
以下这些是假值:
undefined
null
false
+0, -0 和NaN
""
假值的布尔强制类型转换结果为false
理论上 假值列表以外的都应该是真值。
2.
使用 Date.now() 来获取当前时间戳,比new Date().getTime() 简单
3.
~x 大致等于 -(x+1)
~42; // -(42+1) ==> -43
4.
var a = "Hello World";
if(a.indexOf("ol") == -1){
//没有匹配
}
这里是指用-1作为失败时的返回值,这些细节应该被屏蔽。
var a= "Hello World";
~a.indexOf("lo"); // -4 真值
if (~a.indexOf("of")) { //true
//找到匹配
}
~a.indexOf("ol"); // 0 <–假值
!~a.indexOf("ol"); // true
if(!~a.indexOf("ol")){ //true
//没有匹配!
}
5.
~~49.6
~~x 能对小数进行截取,取代Math.floor(xxx),但需要注意负数的情况
~~-49.6 // -49, ~~中的第一个~执行ToInt32并反转字位,然后第二个~再进行一次字位反转,即将所有字位反转回原值,最后得到仍然是ToInt32的结果
Math.floor( -49.6 ) //-50
6.
[] + {} //[Object object] "" + [Object object]
{} + [] //0 {}被当作一个独立的空代码快,不执行任何操作。 代码块结尾不需要分号, 最后+[] 将[]显示强制类型转换
7.
true || false && false; //true (true || false) && false; //false true || (false && false); //true
这说明&&运算符优先于||执行
8.
function foo( a = 42, b = a+1) { console.log( arguments.length, a, b, arguments[0], arguments[1] ) } foo(); //0 42 43 undefined undefined foo( 10 ); //1 10 11 10 undefined foo( 10, undefined ); //2 10 11 10 undefined foo( 10, null ); //2 10 null 10 null
在ES6中,虽然参数a和b都有默认值,但是函数不带参数时,arguments数组为空.
如果向函数传递undefined值,则arguments数组中会出现一个值为undefined的单元
9.
<script>foo();</script>
<script>
function foo() { .. }
</script>
报错,不会进行变量提升
10.
在调试的过程中,有可能对象在console.log(…)语句之后被修改,看到了意料之外的结果,要意识到 这可能是I/O的异步造成的,可以用JSON.stringify()快照一次
第四章
1.Promise中,多次调用reject或resovles,只有第一次有效
new Promise((resovles, reject)=>{ //something resovies(); //只有第一次有效 resovies(); //无效 })
12.Promise中,只能返回第一个参数
new Promise((resovles, reject)=>{ //something resovies(a, b, c); //只返回a })
13. 如果Promies中发生错误,则不往下执行,而是返回一个promise,包含错误信息
var p = new Promise(()=>{xxxx}); var p2 = p.then(()=>{ make some error code //不会报错,也不会运行到下一行 some code },()=>{ //不会执行到这里 }) p2.then((e)=>{ console.log(e) //e就算错误信息 })
14. Promise的局限性有6个
1.Promise链中的错误信息很容易被无意中默默忽略掉
2.只接受单一值返回
3.单决议 // 就是 resolve或rejuect只能运行一次
4.惯性 //就是通常要封装request之类的
5.无法被取消
6.性能稍微低一点点
15.
function *something(){ while(true){ console.log(xxxx) } finally{ console.log("cleaning up!") } } var it = something(); for(var v of it) { console.log(v); if(v > 500){ it.return("end").value; } }
调用it.return(…)之后,它会立即终止生成器,运行finall语句
16.
function *foo(){ console.log( "*foo() starting" ); yield 3; yield 4; console.log( "*foo() finished"); } function *bar() { yield 1; yield 2; yield *foo(); // yield委托 yield 5; } var it = bar(); it.next().value; //1 it.next().value; //2 it.next().value; //*foo() starting 注意观察这里,*bar() 把自己的迭代控制委托给了*foo() //3 it.next().value; //4 it.next().value; //*foo() finished // 5
第五章
1.尾调用优化
function bar(y){ return foo( y + 1); //尾调用 } function baz(){ return 1 + bar( 40 ); //非尾调用 }