JS變數的一些問題

2021-10-02 17:01:12 字數 4739 閱讀 7725

es5變數提公升

變數提公升

//es5

/** 變數提公升:

=> 宣告(declare): var a / function sum (預設值undefined)

=> 定義(defined):a = 12; (就是賦值操作)

=> var 只宣告未定義

=> function 的宣告和賦值,定義

=> 變數提公升只發生當前作用域(開始載入的時候只對全域性作用域下進行提公升,此時函式儲存的是字串)

=> 在全域性作用域下宣告的作用域下宣告的函式或者變數是「全域性變數」,同理,在私有變數作用域下宣告的變數是「私有變數」

=> 瀏覽器做過的事情不會重複第二次,當**執行遇到建立函式這部分**後,直接忽略

sum(...)

呼叫函式時,形成私有作用域,不是立即形成,先形參賦值,再變數提公升,在es5只有在函式內的大括號才有私有作用域,其他大括號沒有

*///帶var的

//在全域性作用域下宣告的變數,相當於給window全域性變數設定屬性,變數值就是屬性值(私有作用域中宣告的私有變數與window無關)

//全域性變數值修改,win下的屬性值有修改,雙方存在「對映機制」

console.

log(a)

;//=>undefined

console.

log(window.a)

;//=>undefined

console.

log(

'a'in window)

;//=>true

var a =12;

console.

log(a)

;//=>12,全域性變數

console.

log(window.a)

;//=>12,window屬性a

//不帶var,本質是window屬性

console.

log(a)

;//=>報錯

console.

log(window.a)

;//=>undefined

console.

log(

'a'in window)

;//=>false

a =12

; = 12 的簡寫,在這裡的window.a才設定存在之前不存在

console.

log(a)

;//=>12,全域性變數

console.

log(window.a)

;//=>12,window屬性a

console.

log(

'a'in window)

;//=>true

var a =

12, b =14;

//=> b帶var

var a = b =12;

//b不帶var, var a = 12; b =12;

//私有作用域中,帶var的私有作用域變數提公升,都宣告為私有變數;不帶var的向上級作用域上找,如果沒有繼續找,一直到window(這種機制叫「作用域鏈」),非私有變數

作用域鏈的擴充套件

如果查詢過程中,沒有找到window的變數,相當於為window設定乙個屬性b

等號左邊的進行變數提公升

fn()

;//=> 只對等號左邊var fn進行變數提公升

sum();

//=>匿名函式的函式表示式,只對等號左邊進行提公升

varfn

=function()

;//=> **執行到此處時把函式值賦值給fn

//=> 普通函式,函式變數提公升

function

sum(

)//可以fn(

);sum(

);

條件判斷下的變數提公升

當前作用域下,不管條件是否成立都要進行變數提公升

帶var 的還是只宣告

帶function的在老版本的瀏覽器中,宣告和定義都處理,新版本瀏覽器迎合es6的塊級作用域,函式(在條件判斷的函式)不管條件是否成立,都只是先宣告沒有定義。

console.

log(a)

;//undefinedif(

1===2)

console.

log(a)

;//undefined

//全域性作用域下變數提公升也相當於給window設定屬性

console.

log(a)

;//undefinedif(

'a'in window)

console.

log(a)

;//10

//函式

f =funcition()

g =funcition()

~function()

//=>對全域性的f進行修改

functiong(

)}}//老版本瀏覽器都為false

console.

log(f(

));console.

log(g(

));/*

變數提公升

function fn;

*/console.

log(fn)

;//undefinedif(

1===1)

}console.

log(fn)

;//函式本身

重名問題

帶var和function 關鍵字宣告相同的名字,也是重名(其實是乙個名字,儲存值的型別不一樣)

關於重名的處理,如果名字重複,不會重新宣告,會重新定義賦值,不管是變數提公升還是**執行階段

fn()

;//4

functionfn(

)fn()

;//4

functionfn(

)fn()

;//4

var fn =

100;fn(

);//typeerror,在變數提公升階段把宣告處理了,到這裡完成賦值

functionfn(

)fn()

;functionfn(

)fn()

;

es6不存在變數提公升

在es6的let/const等方式建立變數或者函式,不存在變數提公升機制

切斷了全域性變數和window屬性的對映機制

在相同的作用域中,基於let不能基於相同的變數(不管使用什麼方式在當前作用域宣告了變數,再次使用let建立都會報錯)

雖然沒有變數提公升(但是瀏覽器記住了當前作用域有哪些變數),但是在**執行前有去重檢測能力,自上而下查詢當前作用域下所有變數,一旦發現有重複就會直接丟擲異常,不再執行

暫時性死區

console.

log(a)

;//=>referenceerror

let a =12;

console.

log(window.a)

;//=>undefined

console.

log(a)

;//=>12

let a =

10, b =10;

console.

log(a)

;letfn=

function()

let a =12;

console.

log(a)

;let a =14;

//syntaxerror

console.

log(a)

;a =12;

//=>referenceerror

console.

log(a)

;let a =14;

console.

log(a)

;/*b = 12;//=>referenceerror

console.log(b);

let a = 14;

console.log(a);

*///暫時性死區

var a =12;

if(true

)當成私有的塊級作用域,在這裡也是重新檢測語法規範,基於新語法檢測

}console.

log(

typeof a)

;//undefined,檢測未宣告變數和es5變數提公升語法一樣,不會報錯

console.

log(

typeof a)

;//=>referenceerror,es6會報錯,解決es5死區

let a;

全域性變數&&私有變數
//es5

var a =12,

b =13,

c =14;

function

fn(a)

fn(a)

;//fn執行(小括號中是實參:值)=>fn(12)

console.

log(a, b, c)

;//=>12, 20, 20

//練習

var ary =[12

,23];

function

fn(ary)

fn(ary)

;console.

log(ary)

;//=>[100,23]

環境變數的一些問題

我們在安裝交叉編譯時往往需要新增環境變數 有兩個地方可以新增 詳細過程見下 最好不要在profile下新增,否則出錯系統就會癱瘓,登陸不進去,指令也無效 那如果我們不小心剛好就遇到這種情況怎麼辦,別問我自己是怎麼辦,看下面 1登入不了 輸入密碼後一直登入不了 使用快捷鍵ctrl alt f1到f6分...

關於JS一些驗證郵箱的一些問題

if type email w w w ig strreg a za z0 9 a za z0 9 a za z0 9 strreg 0 9a za z 0 9a za z 0 9a za z 0 9a za z strreg a za z0 9 a za z0 9 a za z0 9 a za z...

PHP 變數型別中的一些問題

1 整形 echo 027 23?為什麼因為027是八進位制數 2 0.3 0.2 0.1嗎?不等於 為什麼?因為 浮點數的精度有限。儘管取決於系統,php 通常使用 ieee 754 雙精度格式,則由於取整而導致的最大相對誤差為 1.11e 16。非基本數 算可能會給出更大誤差,並且要考慮到進行復...