国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你不知道的javascript(上卷)讀后感(一)

zhaofeihao / 751人閱讀

摘要:遮蔽效應(yīng)作用域查找會在找到第一個匹配的標識符時停止,不會繼續(xù)往上層作用域查找,這就會產(chǎn)生遮蔽效應(yīng)。會發(fā)現(xiàn)每一次輸出的都是為啥勒所有的回調(diào)函數(shù)回在循環(huán)結(jié)束后才會執(zhí)行事件循環(huán)。

三劍客

編譯,顧名思義,就是源代碼執(zhí)行前會經(jīng)歷的過程,分三個步驟,

分詞/詞法分析,將我們寫的代碼字符串分解成多個詞法單元

解析/語法分析,將詞法單元集合生成抽象語法樹(AST)

代碼生成,抽象語法樹(AST)轉(zhuǎn)換成可執(zhí)行代碼的過程

Tip1:js在語法分析和代碼生成階段有對運行性能進行優(yōu)化,對冗余元素進行優(yōu)化

Tip2:js的編譯過程不是發(fā)生在構(gòu)建之前,而是代碼執(zhí)行之前

理解作用域,首先知道三劍客,分別是

引擎:負責整個代碼編譯及執(zhí)行的過程

編譯器: 負責詞法分析、語法分析、代碼生成

作用域:負責維護與收集所有聲明的標識符,保證當前執(zhí)行代碼對這些標識符的訪問權(quán)限

舉例子,加深印象,對于var a = 2,三劍客如何協(xié)同工作,
編譯器進行分詞、語法分析,然后要代碼生成時,遇到 var a,問一下當前作用域集合“你有沒有這個名稱的變量呀?”,作用域如果說有,那么忽略聲明,繼續(xù)編譯,如果說沒有,那么就要要求作用域收集一下,并且給它個名字a,然后編譯器就生成了代碼,引擎準備來執(zhí)行了,先問當前作用域集合,“你這里有a這個變量嗎?”,有引擎就拿來用,沒有就繼續(xù)找該變量,要么找到,就給它附個值2,沒有那就給你報個錯!

理解編譯器的相關(guān)術(shù)語

LSH查詢,通俗解釋就是找到所聲明變量,并且對其賦值的行為

RSH查詢,通俗解釋就是查找聲明的變量

作用域嵌套

當一個塊或是函數(shù)嵌套在另外一個塊或函數(shù)時,就會產(chǎn)生作用域嵌套,于是在當前作用域找不到某個變量時,引擎會往外層嵌套作用域繼續(xù)查找,直達到最外層作用域(全局作用域)為止,也就是所謂的作用域鏈啦!

詞法作用域 相信有很多人都是搞不懂詞法作用域是什么?

所謂的詞法作用域,就是定義在詞法階段(詞法分析)的作用域,由你寫代碼時將變量和塊作用域?qū)懺谀睦飦頉Q定的。

遮蔽效應(yīng)

作用域查找會在找到第一個匹配的標識符時停止,不會繼續(xù)往上層作用域查找,這就會產(chǎn)生遮蔽效應(yīng)

欺騙詞法作用域

eval函數(shù),修改詞法作用域

with關(guān)鍵字,創(chuàng)建詞法作用域

導致性能下降的原因,前面我們提過,在解析/語法分析、生成代碼階段,我們會對代碼進行優(yōu)化,剔除冗余元素,但是當使用eval/with時,所有優(yōu)化變得沒有意義,因為存在不可預見性,不知道修改和創(chuàng)建的詞法作用域是什么?所以會導致性能下降。

函數(shù)聲明、函數(shù)表達式、匿名函數(shù)表達式

函數(shù)表達式:function為第一個詞,那么就是一個函數(shù)聲明,否則就是一個函數(shù)表達式
匿名函數(shù)表達式:沒有函數(shù)名,匿名函數(shù)在棧追蹤這種不會顯示有意義的函數(shù)名,使得調(diào)試困難
IIFE: 立即執(zhí)行函數(shù)表達式((function() { ... }())(function(){ ... })()

塊級作用域

let為其聲明的變量隱式地去劫持了所在的塊級作用域,不會在塊級作用域中進行提升【變量提升】
Demo: with關(guān)鍵字為塊級作用域、{...}為塊級作用域,用完即銷毀
const常量,不可修改!
任何聲明在某個作用域(函數(shù)作用域和塊級作用域)的變量,都是屬于這個作用域。
每個作用域都會進行提升操作。
函數(shù)聲明會被提升,函數(shù)表達式不會提升,變量聲明提升的過程中,函數(shù)會優(yōu)先!

閉包

閉包,有權(quán)訪問另外一個函數(shù)的變量標識符的函數(shù),比較常見的一個閉包問題,就是for循環(huán)。

    for(var i = 1; i <= 5; i++) {
        setTimeout(function() {
            console.log(i);
        }, i*1000)
    }

會發(fā)現(xiàn)每一次輸出的都是6,為啥勒?所有的回調(diào)函數(shù)回在循環(huán)結(jié)束后才會執(zhí)行(事件循環(huán))。所以每次都是輸出一個6來。

解決辦法:

1、IIFE,每個迭代儲存i的值

    for(var i = 1; i <= 5; i++) {
        (function(i) {
            var j = i;
            setTimeout(function() {
                console.log(j);
            }, j*1000);
        })(i)
    }

2、IIFE,將i入?yún)⑿薷某?b>j

    for(var i = 1; i <= 5; i++) {
        (function(j) {
            setTimeout(function() {
                console.log(j);
            }, j*1000);
        })(i)
    }

3、創(chuàng)建閉包的塊作用域

    for(var i = 1; i <= 5; i++) {
        let j = i;
        setTimeout(function() {
            console.log(j);
        }, j*1000);
    }

4、最優(yōu)

    for(let i = 1; i <= 5; i++) {
        setTimeout(function() {
            console.log(i);
        }, i*1000)
    }

另外一個閉包常用的場景,就是模塊暴露了,在這里提供一個現(xiàn)代模塊機制的實現(xiàn)方式,大家可以細細品嘗,

var MyMoudles = (function Manger() {
    var modules = {};
    function define(name, deps, impl) {
        for (var i = 0; i < deps.length; i++) {
            deps[i] = modules[deps[i]];
        }
        modules[name] = impl.apply(impl, deps);
    }
    function get(name) {
        return modules[name];
    }
})()

調(diào)用Demo:

MyMoudles.define("bar", [], function() {
    function hello(who) {
        return "Let me introduce: " + who;
    }
    return {
        hello: hello
    }
})
MyMoudles.define("foo", ["bar"], function(bar) {
    var hungry = "hippo";
    function awesome() {
        console.log(bar.hello(hungry).toUpperCase());
    }
    return {
        awesome: awesome
    }
})
var bar = MyMoudles.get("bar");
var foo = MyMoudles.get("foo");

console.log(bar.hello("hippo")); // Let me introduce: hippo
foo.awesome();
未來模塊機制

ES6提供了全新的模塊機制,基于函數(shù)的模塊(如上述現(xiàn)代模塊機制)并不是一個能被靜態(tài)識別的模式(編譯器無法識別),它們的API語義只有等到代碼運行時才會考慮進來,而ES6模塊就是一個能被靜態(tài)識別的模式,就是說API在編譯階段就會檢查API成員是否存在。

原文地址

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106384.html

相關(guān)文章

  • 你不知道javascript(上卷)后感(二)

    摘要:詞法熟悉語法的開發(fā)者,箭頭函數(shù)在涉及綁定時的行為和普通函數(shù)的行為完全不一致。被忽略的作為的綁定對象傳入,使用的是默認綁定規(guī)則。使用內(nèi)置遍歷數(shù)組返回迭代器函數(shù)普通對象不含有,無法使用,可以進行改造,個人博客地址 this詞法 熟悉ES6語法的開發(fā)者,箭頭函數(shù)在涉及this綁定時的行為和普通函數(shù)的行為完全不一致。跟普通this綁定規(guī)則不一樣,它使用了當前的詞法作用域覆蓋了this本來的值。...

    Ali_ 評論0 收藏0
  • 十分鐘快速了解《你不知道 JavaScript》(上卷

    摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...

    趙春朋 評論0 收藏0
  • 你不知道JavaScript上卷之作用域與閉包·讀書筆記

    摘要:的分句會創(chuàng)建一個塊作用域,其聲明的變量僅在中有效。而閉包的神奇作用是阻止此事發(fā)生。依然持有對該作用域的引用,而這個引用就叫做閉包。當然,無論使用何種方式對函數(shù)類型的值進行傳遞,當函數(shù)在別處被調(diào)用時都可以觀察到閉包。 date: 16.12.8 Thursday 第一章 作用域是什么 LHS:賦值操作的目標是誰? 比如: a = 2; RHS:誰是賦值操作的源頭? 比如: conso...

    Raaabbit 評論0 收藏0
  • 重讀你不知道JS (上) 第節(jié)三章

    摘要:如果是聲明中的第一個詞,那么就是一個函數(shù)聲明,否則就是一個函數(shù)表達式。給函數(shù)表達式指定一個函數(shù)名可以有效的解決以上問題。始終給函數(shù)表達式命名是一個最佳實踐。也有開發(fā)者干脆關(guān)閉了靜態(tài)檢查工具對重復變量名的檢查。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復雜微妙技術(shù)的語言,即使是經(jīng)驗豐富的 Ja...

    lavor 評論0 收藏0
  • 重讀你不知道JS (上) 第節(jié)五章

    摘要:詞法作用域的查找規(guī)則是閉包的一部分。因此的確同閉包息息相關(guān),即使本身并不會真的使用閉包。而上面的創(chuàng)建一個閉包,本質(zhì)上這是將一個塊轉(zhuǎn)換成一個可以被關(guān)閉的作用域。結(jié)合塊級作用域與閉包模塊這個模式在中被稱為模塊。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復雜微妙技術(shù)的語言,即使是經(jīng)驗豐富的 Jav...

    worldligang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<