月度存档: 八月 2018

《你不知道的Javascript-上册》阅读笔记

第一部分  作用域和闭包

第三章

 1.

{
    console.log( bar ); //Error
    let bar = 2;
}

说明1. let 函数没有变量提升这个说法, 

       2. 在大括号内就能产生块作用域

第四章

1.

foo(); //error
{
function foo() {console.log("b")}
}

说明函数的提升只在自己的块级作用域有效

console.log(a) //undefined 注意不是error
{
var a;
}

说明var的声明提升可以在子级的块级作用域有效

2.

JavaScript中的作用域就是词法作用域

function foo() {
  console.log(a); //2
}
function bar() {
  var a = 3;
  foo();
}
var a = 2;
bar();

3.

var fun = function foo() {console.log("b")}
fun();  //b
foo(); // error

说明同时使用2个变量命名的函数,会忽略后面一个

第二部分 this解析

当判断this的真实对象时,需要应用下面四条规则中的其中一条:

  1. 默认绑定

     this 一般指向全局对象,严格模式是undefined

      function foo(){
            console.log(this.a);  //use strict 只对当前块级作用域有效,所以这里不是undefined
     }
    var a = 2;
    
    (function(){
        "use strict";
        foo();//2
    })();

    foo() 是直接使用不带任何修饰的函数进行调用的,因此属于默认绑定

    2.隐式绑定

    obj.foo()  //类似这种有上下文调用的

    3.显示调用

     call,apply,bind

    4. new 一个实例

2. 

function foo() {
    console.log(this.a);
}
var a = 2;
foo.call( null );//2

如果call,apply,bind传入null,则应用默认绑定

3.

function foo()
{
    return (a)=> {
    console.log(this.a)
    }
}
 
var obj1 = {
    a:2
}
 
var obj2 = {
    a:3
}
 
var bar = foo.call(obj1);
bar.call(obj2); //2

foo()调用一次时,箭头函数中的this获得 obj1 , 由于箭头函数一旦获得this,就无法被修改,所以还是obj1

 第三章 对象

  1. 深度复制对象时,要注意循环引用的问题

第五章 原型

  1. 判断两个对象之间的关系,可以用

 b.isPrototypeOf( c );

2. 使用Class的一个缺点:

class C{
    constructor{}{
        C.prototype.count++
        console.log("Hello:" + this.count);
    }
    C.prototype.count = 0;
    var c1 = new C();
    //Hello:1
    var c2 = new C();
    //Hello:2
    c1.count === 2;//trte
    c1.count === c2.count;//true
}

这种方法问题是,它违背了class语法的本意。在实现中暴露了.prototype

如果使用 this.count++ 我们会发现 c1,c2上都创建了 .count属性,而且互相共享