《你不知道的JavaScript 上卷》

這裏寫圖片描述

catch會創建塊作用域

有點驚呆 O_o

聲明提升

函數首先被提升,然後纔是變量。

後面的函數聲明可以覆蓋前面的。

神話般的存在:閉包

閉包是詞法作用域產生的自然結果,這意味着作用域是由聲明的位置決定的。

一個例子觀察閉包

function foo() {
    var a = 2;

    function bar() {
        console.log(a);
    }

    return bar;
}

var baz = foo();
baz();

foo()執行完之後,其內部作用域並沒有銷燬,因爲還有baz指向foo內部作用域的bar

this

this 是在運行時進行綁定的,而不是在編寫時綁定。

有四種綁定場景

(1) 默認綁定

非嚴格模式下綁定到全局對象,嚴格模式下綁定到 undefined

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

'use strict';
function foo() {
    console.log(this.a);
}
var a = 2;
foo(); // Uncaught TypeError: Cannot read property 'a' of undefined

(2) 隱式綁定

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2,
    foo: foo
};
obj.foo();

(3) 顯式綁定

即 call、apply、bind

(4) new 綁定

this 綁定到新創建的對象

優先級

可以猜到的是

隱式綁定 > 默認綁定
顯式綁定 > 默認綁定
new 綁定 > 默認綁定

隱式綁定和顯示綁定誰的優先級高?

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

顯式綁定 > 隱式綁定

new 綁定和顯式綁定誰的優先級高?

function foo(value) {
    this.a = value;
}
var obj = {
    a: 2
};
var bar = foo.bind(obj);
var baz = new bar(3);
console.log(baz.a); // 3

new 綁定 > 顯式綁定

所以,new 綁定 > 顯式綁定 > 隱式綁定 > 默認綁定

綁定到null與undefined

如果把 null 或者 undefined 傳入call、apply或者 bind,調用時會被忽略,應用的是默認綁定。

箭頭函數

箭頭函數是根據外層作用域來決定 this

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

null 和 undefined 沒有對應的包裝對象

只有 number、string、boolean 有包裝對象。

面向對象還是行爲委託?

作者對在 JS 中使用面向對象的行爲狠狠吐槽了一番,包括 class 關鍵字的引入。

這裏不是說面向對象的思想有問題,而是 JS 中”僞面向對象”的寫法好不好。

行爲委託倡導的是直接創建和關聯對象,不把它們抽象成類,而是順着 JS 的 [[Prototype]] 機制寫。

不過,一個不可否認的狀況是:ES6 的 class 讓人更難看清 JS 的真面目了。

發佈了237 篇原創文章 · 獲贊 91 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章