成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

YouDontKnowJS 小黃書學(xué)習(xí)小結(jié)

Yuqi / 1082人閱讀

摘要:真正的理解閉包的原理與使用更加透徹綁定的四種規(guī)則機(jī)制你不知道的人稱小黃書,第一次看到這本書名就想到了一句話你懂得,翻閱后感覺到很驚艷,分析的很透徹,學(xué)習(xí)起來也很快,塊級(jí)作用域語句語句相當(dāng)于比較麻煩而且用在對(duì)象上創(chuàng)建的塊作用域僅僅在聲明中有效

真正的理解閉包的原理與使用 更加透徹this綁定的四種規(guī)則機(jī)制  
你不知道的JavaScript 人稱小黃書,第一次看到這本書名 就想到了一句話 “You konw nothing! Jon snow”(你懂得), 翻閱后感覺到很驚艷,分析的很透徹,學(xué)習(xí)起來也很快,Have fun!
塊級(jí)作用域

if語句

for語句

with

with(obj) {
    a = 1;
    b = 2;
    c = 3;
}

相當(dāng)于

obj.a = 1;

obj.b = 2;

obj.c = 3; (比較麻煩)

而且用with在對(duì)象上創(chuàng)建的塊作用域僅僅在with聲明中有效

try / catch

catch 事實(shí)上也會(huì)創(chuàng)建一個(gè)塊作用域,且僅僅在catch內(nèi)部有效

let

const

塊作用域的用處

垃圾回收

let循環(huán)

聲明提升

a = 2;

var a;

console.log(a); // 2

這就是聲明提升,先有蛋(聲明),后有雞(賦值)

只有聲明被提升,賦值或其他邏輯保留在原地

真正的順序是

var a (未執(zhí)行前,在編譯階段)

a = 2 (等待執(zhí)行)

console.log(a)

函數(shù)聲明會(huì)被提升,而函數(shù)表達(dá)式不會(huì)

函數(shù)聲明,變量聲明同時(shí)出現(xiàn)(一般不會(huì)出現(xiàn),出現(xiàn)情況是重復(fù)聲明), 則是 函數(shù)優(yōu)先
作用域閉包

閉包實(shí)質(zhì): 當(dāng)函數(shù)可以記住并訪問所在的詞法作用域時(shí),就產(chǎn)生了閉包,即使函數(shù)在當(dāng)前詞法作用域之外執(zhí)行

將內(nèi)部函數(shù)傳遞到詞法作用域外,他都會(huì)有對(duì)原始定義作用域的引用,無論在何處執(zhí)行這個(gè)函數(shù)都會(huì)使用閉包

在定時(shí)器,時(shí)間監(jiān)聽器,Ajax請(qǐng)求,跨窗口通信,web workers 或者其他任何異步任務(wù),只要使用了

回調(diào)函數(shù),實(shí)際上都是在使用到了閉包

IIFE:立即執(zhí)行函數(shù),典型的閉包例子,IIFE會(huì)通過聲明并立即執(zhí)行函數(shù)創(chuàng)建作用域

經(jīng)典栗子

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i)
    },0);
}  // output: 5 5 5 5 5
// setTimeoiut延遲函數(shù)會(huì)在循環(huán)結(jié)束之后執(zhí)行 ,而此時(shí)i為5 結(jié)果自然為5個(gè)5
//利用閉包解決,創(chuàng)建一個(gè)塊作用域保存一個(gè)i的副本即可
@方法1
for(var i = 0; i < 5; i++) {
    (function() {
        var j = i;
        setTimeout(function() {
            console.log(j);
        },0);
    })();
} // output: 0 1 2 3 4 
@方法2
for(var i = 0; i < 5; i++) {
    (function(j) {
        setTimeout(function() {
            console.log(j);
        },0);
    })(i);
} // output: 0 1 2 3 4 
@方法3 (let即可,簡單實(shí)用)
for(let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i)
    },0);
}  // output: 0 1 2 3 4
模塊機(jī)制

現(xiàn)代模塊

var MyModules = (function manager() {
    var modules = {};
    function define(name, deps, imp) {
        //...
        modules[name] = imp.apply(imp, deps);
    };
    function get(name) {
        return modules[name];
    };
    return {
        define: define,
        get: get
    };
})();

未來模塊機(jī)制

bar.js
    function add(a, b){
        return  a + b;
    }
    export add;

foo.js
    import bar from "bar"
    console.log(bar.add());

特征

為創(chuàng)建一個(gè)內(nèi)部作用域而調(diào)用一個(gè)包裝的函數(shù)

包裝函數(shù)的返回值必須至少包含一個(gè)內(nèi)部函數(shù)的引用, 這才會(huì)創(chuàng)建涵蓋整個(gè)包裝函數(shù)內(nèi)部作用域的閉包

關(guān)于This
為什么要用 this

? 1. this提供了一種更加優(yōu)雅的方式來隱式傳遞 一個(gè) 對(duì)象的引用,使API設(shè)計(jì)的更加簡潔與重復(fù)使用

? 2.this既不指向函數(shù)自身,也不指向函數(shù)的詞法作用域

? 3.實(shí)質(zhì)是在函數(shù)調(diào)用發(fā)生的綁定,指向完全取決于函數(shù)在哪里被調(diào)用

四種綁定方法:

1.默認(rèn)綁定

function foo(){
    console.log(this.a);
}
var a = 2;
foo(); //2
// this默認(rèn)指向window

2.隱式綁定

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2,
    foo: foo
}
obj.foo(); //2
會(huì)存在隱式丟失綁定對(duì)象,丟失后就成為 默認(rèn)綁定(指向全局對(duì)象)

3.顯示綁定

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2
}
foo.call( obj ); //2
通過call(),apply() 顯示綁定,也會(huì)存在綁定丟失問題 call(this,參數(shù)列表),apply(this,args),效果相同,參數(shù)不同

硬綁定可以解決,但是一旦綁定,則不能再修改this

4.new綁定

javascript 的 new操作與其 他語言的new操作 很大的不同

new 的四個(gè)實(shí)質(zhì)過程

創(chuàng)一個(gè)全新的對(duì)象

新對(duì)象會(huì)被執(zhí)行[[Prototype]]鏈接

新對(duì)象會(huì)被綁定到函數(shù)調(diào)用的this

若函數(shù)沒有返回其他對(duì)象,new表達(dá)式的函數(shù)調(diào)用會(huì)自動(dòng)返回這個(gè)新對(duì)象

function foo() {
    this.a = a;  
}  
var bar = new foo(2);
console.log(bar.a); // 2
上面四種綁定的優(yōu)先級(jí)
new綁定  >  顯示綁定  >  隱式綁定  >  默認(rèn)綁定

默認(rèn)綁定優(yōu)先級(jí)最低;

顯示綁定比隱式綁定優(yōu)先級(jí)更高

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

obj1.foo.call( obj2 ); // 隱式,顯示 同在  顯示優(yōu)先 4
obj2.foo.call( obj1 ); // 2 
new綁定比隱式綁定優(yōu)先級(jí)更高
function foo(some) {
    this.a = some;
} 
var obj1 = {
    foo: foo
};
var obj2 = {};
obj1.foo(2);  
console.log(obj1.a); //2
obj1.foo.call(obj2, 3);
console.log(obj2.a); //3

var bar = new obj1.foo(4);
console.log(obj1.a); // 隱式綁定 2
console.log(bar.a);  // new綁定 4
new綁定 與 顯示綁定比較
function foo(some) {
    this.a = some;
}
var obj = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a); // 2J

var baz = new bar(3);
console.log(obj1.a); // 2
console.log(baz.a);  // 3
// new 修改了硬綁定 bind()中的this
箭頭函數(shù)的特殊 this

ES6中特殊函數(shù)類型 箭頭函數(shù) 并不適用于上面四中綁定方式規(guī)則

箭頭函數(shù) 根據(jù)函數(shù)或則全局作用域決定this

function foo() {
    return (a) => {
       // this繼承foo
       console.log(this.a);
    };
}
var ojb1 = {
    a: 2
}
var obj2 = {
    a: 3
}
var bar = foo.call(obj1); 
bar.call(obj2); // 2 
foo()的this綁定到obj1,而且bar 的this也會(huì)綁定到obj1 ,箭頭函數(shù)的綁定無法被修改,new 也不能將其修改
兩種代碼風(fēng)格的使用

var that = this

箭頭函數(shù)

箭頭函數(shù)
function foo() {
    setTimeout(() => {
        console.log(this.a); //若不適用箭頭函數(shù),則綁定丟失,this默認(rèn)綁定到去全局 為 1
    }, 1000);
}
var obj = {
    a: 2
};
var a = 1;
foo.call(obj);// 2
******************************************************************************
使用 that = this
function foo() {
    var that = this;
    setTimeout(function() {
        console.log(that.a); //用that傳遞原this的詞法作用域
    },1000);
}
var obj = {
    a: 2
};
foo.call(obj); //2 

tips: 兩種風(fēng)格最好不要混合使用,不然很難維護(hù),筆者本人還是比較喜歡使用 that 而不是箭頭函數(shù)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99972.html

相關(guān)文章

  • JavaScript 異步和回調(diào)函數(shù)

    摘要:異步找到書前一個(gè)任務(wù)完成就回電話執(zhí)行回調(diào)函數(shù),而后一個(gè)任務(wù)找書不管前一個(gè)任務(wù)是否完成都會(huì)開始?;卣{(diào)函數(shù)回調(diào)函數(shù)是實(shí)現(xiàn)異步編程的最基本的方法。 JavaScript語言的執(zhí)行環(huán)境是單線程的,即是一次只能完成一個(gè)任務(wù),其他任務(wù)排隊(duì)等候執(zhí)行。只有當(dāng)前一個(gè)任務(wù)完成時(shí),才能開始進(jìn)行下一個(gè)任務(wù)。 這種模式的執(zhí)行環(huán)境簡單,若是遇到一個(gè)耗時(shí)較長的任務(wù),將會(huì)拖延整個(gè)程序的執(zhí)行。 為了解決這個(gè)問題,我們有...

    HtmlCssJs 評(píng)論0 收藏0
  • (動(dòng)手)攔截getter,setter

    前言 首先出道面試上機(jī)題簡化版(來自喜馬拉雅Fm),侵刪。 **** 你需要在這里完成People的構(gòu)造函數(shù) **** //從而會(huì)按照期望執(zhí)行下面的代碼 var man = new People(小明); var women = new People(小紅) console.log(ma...

    YuboonaZhang 評(píng)論0 收藏0
  • MyBatis 源碼分析系列文章合集

    摘要:簡介我從七月份開始閱讀源碼,并在隨后的天內(nèi)陸續(xù)更新了篇文章??紤]到超長文章對(duì)讀者不太友好,以及拆分文章工作量也不小等問題。經(jīng)過兩周緊張的排版,一本小小的源碼分析書誕生了。我在寫系列文章中,買了一本書作為參考,這本書是技術(shù)內(nèi)幕。 1.簡介 我從七月份開始閱讀MyBatis源碼,并在隨后的40天內(nèi)陸續(xù)更新了7篇文章。起初,我只是打算通過博客的形式進(jìn)行分享。但在寫作的過程中,發(fā)現(xiàn)要分析的代碼...

    Crazy_Coder 評(píng)論0 收藏0
  • 從兩個(gè)小例子看js中的隱式類型轉(zhuǎn)換

    摘要:來看代碼上面的代碼不難理解變量是通過構(gòu)造函數(shù)創(chuàng)建的對(duì)象,變量就是一個(gè)很簡單的數(shù)值。一開始,因?yàn)槭峭ㄟ^構(gòu)造函數(shù)創(chuàng)建的對(duì)象,所以值為然后每一次在執(zhí)行的時(shí)候,會(huì)調(diào)用一次的方法。 廢話不多說,我們先來看第一個(gè)例子吧。某天,我遇到了這樣一個(gè)問題:給出變量a和b的定義,使下面三個(gè)語句的輸出結(jié)果都為true。 console.log(ab); 看到題目的我第一反應(yīng)是懵逼的,還有這樣的操作???然后一...

    liukai90 評(píng)論0 收藏0
  • ??《小黃鴨調(diào)試法》程序員必備技能?。???

    小黃鴨調(diào)試法 場景一:我們都有過向別人(甚至可能向完全不會(huì)編程的人)提問及解釋編程問題的經(jīng)歷,但是很多時(shí)候就在我們解釋的過程中自己卻想到了問題的解決方案,然后對(duì)方卻一臉茫然。 場景二:你的同行跑來問你一個(gè)問題,但是當(dāng)他自己把問題說完,或說到一半的時(shí)候就想出答案走了,留下一臉茫然的你。 其實(shí)上面兩種場景現(xiàn)象就是所謂的小黃鴨調(diào)試法(Rubber Duck Debuging),又稱橡皮鴨調(diào)試法,它是我們...

    mj 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<