第一部分
第一章
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 ); //非尾调用
}