欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

為什么說JavaScript預(yù)解釋是一種毫無節(jié)操的機(jī)制詳析

 更新時(shí)間:2018年11月18日 14:22:06   作者:浪里行舟  
這篇文章主要給大家介紹了關(guān)于為什么說JavaScript預(yù)解釋是一種毫無節(jié)操的機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧

前言

JavaScript是一門解釋型的語言 , 想要運(yùn)行JavaScript代碼需要兩個(gè)階段

  • 編譯階段: 編譯階段就是我們常說的JavaScript預(yù)解釋(預(yù)處理)階段,在這個(gè)階段JavaScript解釋器將完成把JavaScript腳本代碼轉(zhuǎn)換到字節(jié)碼
  • 執(zhí)行階段: 在編譯階段JavaScript解釋器借助執(zhí)行環(huán)境把字節(jié)碼生成機(jī)械碼,并從上到下按順序執(zhí)行

本文就重點(diǎn)介紹預(yù)解釋,框架圖如下:

一、什么是預(yù)解釋

在js中,帶var 和function關(guān)鍵字的需要預(yù)解釋:

那什么是預(yù)解釋?就是在js代碼執(zhí)行之前,先申明好帶有var 關(guān)鍵字和帶有function關(guān)鍵字的變量,在內(nèi)存里先安排好。

預(yù)解釋:JavaScript代碼執(zhí)行之前,瀏覽器首先會(huì)默認(rèn)的把所有帶var和function的進(jìn)行提前的聲明或者定義

1.理解聲明和定義

聲明(declare):如var num;=>告訴瀏覽器在全局作用域中有一個(gè)num的變量了;如果一個(gè)變量只是聲明了但是沒有賦值,默認(rèn)的值是undefined

定義(defined):如num=12;=>給我們的變量進(jìn)行賦值。

2.對(duì)于帶var和function關(guān)鍵字的在預(yù)解釋的時(shí)候操作不一樣的

var =>在預(yù)解釋的時(shí)候只是提前的聲明

function =>在預(yù)解釋的時(shí)候提前的聲明+定義都完成了

3.預(yù)解釋只發(fā)生在當(dāng)前的作用域下。

例如:開始只對(duì)window下的進(jìn)行預(yù)解釋,只有函數(shù)執(zhí)行的時(shí)候才會(huì)對(duì)函數(shù)中的進(jìn)行預(yù)解釋

二、作用域鏈

1.如何區(qū)分私有變量和全局變量?

1)在全局作用域下聲明(預(yù)解釋的時(shí)候)的變量是全局變量

2)只有函數(shù)執(zhí)行會(huì)產(chǎn)生私有的作用域,比如for(){}、if(){}和switch(){}都不會(huì)產(chǎn)生私有作用域

3)在"私有作用域中聲明的變量(var 聲明)"和"函數(shù)的形參"都是私有的變量。在私有作用域中,代碼執(zhí)行的時(shí)保遇到了一個(gè)變量,首先我們需要確定它是否為私有的變量,如果是私有的變量,那么和外面的沒有在何的關(guān)系;如果不是私有的,則往當(dāng)前作用域的上級(jí)作用域進(jìn)行查找,如果上級(jí)作用域也沒有則繼續(xù)查找,一直找到window為止,這就是作用域鏈。

我們舉個(gè)例子來區(qū)別私有變量和全局變量:

//=>變量提升:var a;var b;var c;test=AAAFFF111;
var a=10,b=11,c=12;
function test(a){
//=>私有作用域:a=10 var b;
a=1;//=>私有變量a=1
var b=2;//=>私有變量b=2
c=3;//=>全局變量c=3
}
test(10);
console.log(a);//10
console.log(b);//11
console.log(c);//3

判斷是否是私有變量一個(gè)標(biāo)準(zhǔn)就是是否是在函數(shù)中var聲明的變量和函數(shù)的形參都是私有的變量。本道題目在test函數(shù)中a是形參和var b定義的變量b都是私有變量。

2.函數(shù)傳參

這是因?yàn)楫?dāng)函數(shù)執(zhí)行的時(shí)候,首先會(huì)形成一個(gè)新的私有的作用域,然后按照如下的步驟執(zhí)行:

1)如果有形參,先給形參賦值

2)進(jìn)行私有作用域中的預(yù)解釋

3)私有作用域中的代碼從上到下執(zhí)行

我們來看一道例題

var total=0;
function fn(num1,num2){
console.log(total);//->undefined 外面修改不了私有的
var total=num1 +num2;
console.log(total);//->300
}
fn(100,200);
console.log(total);//->0 私有的也修改不了外面的

3.JS中內(nèi)存的分類

棧內(nèi)存:用來提供一個(gè)供JS代碼執(zhí)行的環(huán)境,即作用域(全局作用域/私有的作用域)

堆內(nèi)存:用來存儲(chǔ)引用數(shù)據(jù)類型的值。對(duì)象存儲(chǔ)的是屬性名和屬性值,函數(shù)存儲(chǔ)的是代碼字符串。

三、全局作用域下帶var和不帶var的區(qū)別

我們先來看以下兩個(gè)例子:

//例題1
console.log(num);//->undefined
var num=12;
//例題2
console.log(num2);//->Uncaught ReferenceError:num2 is not defined 
num2=12;//不能預(yù)解釋

當(dāng)你看到var num=12時(shí),可能會(huì)認(rèn)為只是個(gè)聲明。但JavaScript實(shí)際上會(huì)將其看成兩條聲明語句:var num;num=12;第一個(gè)定義聲明是在預(yù)解釋階段進(jìn)行的。第二個(gè)賦值聲明會(huì)被留在原地等待執(zhí)行階段。num2=12 相當(dāng)于給window增加了一個(gè)叫做num2的屬性名,屬性值是12;而var num=12 首先它相當(dāng)于給全局作用域增加了一個(gè)全局變量num,它也相當(dāng)于給window增加了一個(gè)屬性名num2,屬性值是12。兩者最大區(qū)別:帶var的可以進(jìn)行預(yù)解釋,所以在賦值的前面執(zhí)行不會(huì)報(bào)錯(cuò);不帶var的是不能進(jìn)行預(yù)解釋的,在前面執(zhí)行會(huì)報(bào)錯(cuò);

接下來我們舉例說明:

//例題1
var total=0;
function fn(){
console.log(total);//undefined
var total=100;
}
fn();
console.log(total);//0
//例題2
var total=0;
function fn(){
console.log(total);//0
total=100;
}
fn();
console.log(total);//100

例題1中帶var變量在私有作用域中可以預(yù)解釋,所以第一個(gè)console打出來的值為undefined。私有作用域中出現(xiàn)的一個(gè)變量不是私有的,則往上級(jí)作用域進(jìn)行查找,上級(jí)沒有則繼續(xù)向上查找,一直找到window為止,例題2中不帶var變量不是私有的,所以往上級(jí)找

四、預(yù)解釋五大毫無節(jié)操的表現(xiàn)

1.預(yù)解釋的時(shí)候不管你的條件是否成立,都要把帶var的進(jìn)行提前的聲明。

請(qǐng)看下面這道例題:

if(!("num" in window)){
var num=12;//這句話會(huì)被提到大括號(hào)之外的全局作用域:var num;->window.num; 
}
console.log(num);//undefined

2.預(yù)解釋的時(shí)候只預(yù)解釋”=”左邊的,右邊的值,不參與預(yù)解釋

請(qǐng)看下面這道例題:

fn();//報(bào)錯(cuò)
var fn=function (){ //window下的預(yù)解釋:var fn;
console.log("ok");
};

3.自執(zhí)行函數(shù):定義和執(zhí)行一起完成了。

自執(zhí)行函數(shù)定義的那個(gè)function在全局作用域下不進(jìn)行預(yù)解釋,當(dāng)代碼執(zhí)行到這個(gè)位置的時(shí)候定義和執(zhí)行一起完成了。常見有以下幾種形式:

(function(num){})(10);
~function(num){}(10);
+function(num){}(10);
-function(num){}(10);
!function(num){}(10);

4.函數(shù)體中return下面的代碼雖然不再執(zhí)行了,但是需要進(jìn)行預(yù)解釋;return后面跟著的都是我們返回的值,所以不進(jìn)行預(yù)解釋;

function fn(){
//預(yù)解釋:var num;
console.log(num);//->undefined
return function(){};
var num=100;
}

5.函數(shù)聲明和變量聲明都會(huì)被提升。但是一個(gè)值得注意的細(xì)節(jié)(這個(gè)細(xì)節(jié)可以出現(xiàn)在有多個(gè)“重復(fù)”聲明的代碼中)是函數(shù)會(huì)首先被提升,然后才是變量。在預(yù)解釋的時(shí)候,如果名字已經(jīng)聲明過了,不需要從新的聲明,但是需要重新的賦值;
我們先來看下兩個(gè)簡(jiǎn)單的例子:

//例題1
 function a() {}
 var a
 console.log(typeof a)//'function'
//例題2
 var c = 1
 function c(c) {
 console.log(c)
 var c = 3
 }
 c(2)//Uncaught TypeError: c is not a function

當(dāng)遇到存在函數(shù)聲明和變量聲明都會(huì)被提升的情況,函數(shù)聲明優(yōu)先級(jí)比較高,最后變量聲明會(huì)被函數(shù)聲明所覆蓋,但是可以重新賦值,所以上個(gè)例子可以等價(jià)為

 function c(c) {
 console.log(c)
 var c = 3
 }
 c = 1
 c(2)

接下來我們看下兩道比較復(fù)雜的題目:

//例題3
fn();
function fn(){console.log(1);};
fn();
var fn=10;
fn();
function fn(){console.log(2);};
fn();

1.一開始預(yù)解釋,函數(shù)聲明和賦值一起來,fn 就是function fn(){console.log(1);};遇到var fn=10;不會(huì)重新再聲明,但是遇到function fn(){console.log(2);}就會(huì)從重新賦值,所以一開始fn()的值就是2

2.再執(zhí)行fn();值不變還是2

3.fn重新賦值為10,所以運(yùn)行fn()時(shí)報(bào)錯(cuò),接下去的語句就沒再執(zhí)行。

//例題4
alert(a);
a();
var a=3;
function a(){
alert(10)
}
alert(a);
a=6;
a()

1.函數(shù)聲明優(yōu)先于變量聲明,預(yù)解釋時(shí)候,函數(shù)聲明和賦值一起來,a就是function a(){alert(10)} ,后面遇到var a=3,也無需再重復(fù)聲明,所以先彈出function a(){alert(10)}

2.a() ,執(zhí)行函數(shù),然后彈出10

3.接著執(zhí)行了var a=3; 所以alert(a)就是顯示3

4.由于a不是一個(gè)函數(shù)了,所以往下在執(zhí)行到a()的時(shí)候, 報(bào)錯(cuò)。

參考文章

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 前端使用Compressor.js實(shí)現(xiàn)圖片壓縮上傳的詳細(xì)過程

    前端使用Compressor.js實(shí)現(xiàn)圖片壓縮上傳的詳細(xì)過程

    Compressor.js一個(gè)JavaScript圖像壓縮器,使用瀏覽器的原生canvas.toBlob API來執(zhí)行壓縮工作,這篇文章主要給大家介紹了關(guān)于前端使用Compressor.js實(shí)現(xiàn)圖片壓縮上傳的詳細(xì)過程,需要的朋友可以參考下
    2024-07-07
  • JS Html轉(zhuǎn)義和反轉(zhuǎn)義(html編碼和解碼)的實(shí)現(xiàn)與使用方法總結(jié)

    JS Html轉(zhuǎn)義和反轉(zhuǎn)義(html編碼和解碼)的實(shí)現(xiàn)與使用方法總結(jié)

    這篇文章主要介紹了JS Html轉(zhuǎn)義和反轉(zhuǎn)義(html編碼和解碼)的實(shí)現(xiàn)與使用方法,結(jié)合實(shí)例形式總結(jié)分析了JS Html轉(zhuǎn)義和反轉(zhuǎn)義、html編碼和解碼相關(guān)封裝類定義與具體使用技巧,需要的朋友可以參考下
    2020-03-03
  • 詳解Javascript獲取緩存和清除緩存API

    詳解Javascript獲取緩存和清除緩存API

    本篇文章主要介紹了詳解Javascript獲取緩存和清除緩存API,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • JS中可以改善代碼的5種重構(gòu)技術(shù)分享

    JS中可以改善代碼的5種重構(gòu)技術(shù)分享

    代碼重構(gòu)涉及在不改變其外部功能的情況下對(duì)現(xiàn)有代碼進(jìn)行改進(jìn),這是編程的核心部分之一,所以下面我們將研究一些技巧,這些技巧可以幫助我們以更好的方式重構(gòu)代碼,希望對(duì)大家有所幫助
    2023-06-06
  • 如何使用JavaScript實(shí)現(xiàn)棧與隊(duì)列

    如何使用JavaScript實(shí)現(xiàn)棧與隊(duì)列

    這篇文章主要介紹了如何使用JavaScript實(shí)現(xiàn)棧與隊(duì)列。棧和隊(duì)列是web開發(fā)中最常用的兩種數(shù)據(jù)結(jié)構(gòu)。絕大多數(shù)用戶,甚至包括web開發(fā)人員,都不知道這個(gè)驚人的事實(shí)。,需要的朋友可以參考下
    2019-06-06
  • js通用滑動(dòng)門類

    js通用滑動(dòng)門類

    可以實(shí)現(xiàn)滑動(dòng)門效果代碼類
    2008-04-04
  • 基于js實(shí)現(xiàn)抽紅包并分配代碼實(shí)例

    基于js實(shí)現(xiàn)抽紅包并分配代碼實(shí)例

    這篇文章主要介紹了基于js實(shí)現(xiàn)抽紅包并分配代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 使用js獲取偽元素的content實(shí)例

    使用js獲取偽元素的content實(shí)例

    下面小編就為大家?guī)硪黄褂胘s獲取偽元素的content實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 一些常用彈出窗口/拖放/異步文件上傳等實(shí)用代碼

    一些常用彈出窗口/拖放/異步文件上傳等實(shí)用代碼

    今天寫一點(diǎn)工作中遇到的東西【彈出窗口】【拖放】【異步文件上傳】,大家共同學(xué)習(xí),共同進(jìn)步
    2013-01-01
  • js星星評(píng)分效果

    js星星評(píng)分效果

    在這里和廣大腳本之家站的朋友們分享一個(gè)使用js實(shí)現(xiàn)商城星星評(píng)分的效果,希望能給大家點(diǎn)幫助
    2014-07-07

最新評(píng)論