編譯階段報錯提示referenceerror
執行階段報錯提示typeerror
宣告變數假設理解為包括建立、初始化、賦值。
var a;
// 建立、初始化為undefined
var b =1;
// 建立、初始化、賦值
建立會在編譯階段分析並提公升。
賦值在執行階段執行。
編譯階段js引擎的編譯器會將var
宣告變數的建立和初始化提公升到作用域頂部,並忽略重複的宣告。
console.
log(a)
;var a =1;
var a =
2;
會被引擎理解為:
var a = undefined;
console.
log(a)
a =1
;a =2;
// 重複宣告被忽略,保留賦值操作
宣告乙個函式有兩個方式:
function a() {}
函式宣告式也會被提公升,與var
不同的是:
它的定義(賦值)也會被提公升
提公升的優先順序高於變數宣告
foo()
;var foo =1;
function
foo(
)
會被理解為:
function
foo(
)// 建立和賦值都被提公升
// var foo = undefined; 函式提公升高於變數提公升,這裡重複宣告被忽略
foo =
1;
匿名函式表示式var a = function() {}
具名函式表示式var a = function aa() {}
console.
log(a)
vara
=function
foo();
foo(
)
會被理解為
var a = undefined;
console.
log(a)a=
function
foo();
foo(
)// 當前作用域查詢不到foo,這裡在編譯階段報錯
es6增加了新的宣告方式let const
,是對var
的擴充套件,除了實現了塊作用域和常量功能,在變數提公升方便也做了限制。
建立操作依然被提公升。
初始化和賦值沒有被提公升。
let const
不允許使用未初始化的變數
let a =1;
會被理解為
let a = undefined;
a =1
;
思考下面的**
function
foo(a, b)
}foo(1
,2);
// 1, f b(){}
這段**沒研究明白的地方是引數的賦值是在哪個階段?
當前我只能理解為這樣
function
foo(a, b)
// 函式宣告提公升到頂部
// var a; // 同作用域的宣告被忽略
console.
log(a, b)
; a =3;
}}foo(1,
2)
因為在函式體內用let
宣告與引數同名的變數會報錯,說明任務a
和任務b
屬於同乙個作用域。
所以只能理解為函式體在編譯時區分了任務,而不是區分了作用域。
等大佬解答原理
所有的宣告都會提公升到作用域頂部。
var
宣告提公升建立、初始化。
let const
宣告只提公升建立,不提公升。
函式宣告提公升建立、初始化、賦值。且優先順序高於字面量宣告。
同乙個變數只會宣告一次,其它的會被忽略或覆蓋。
ES6學習筆記之ES6中的模組
1 import和export基本使用 重點 在es6中新增了js檔案的暴露和引入的新寫法 import和export node es6 require import exports.export module.exports default 使用export const 暴露函式名暴露函式,imp...
ES6 學習 之 解構賦值
es6允許按照一定模式從資料和物件中提取值,對變數進行賦值,這被稱為解構 destructuring let name 張三 age 18,男 let name,age,李四 20,女 name aaa console.log name aaa console.log age 20 console....
ES6之Class學習筆記
prototype 是類或者方法的 方法,proto 是new 之後的例項的方法。constructor方法是類的預設方法,通過new命令生成物件例項時,自動呼叫該方法。乙個類必須有constructor方法,如果沒有顯式定義,乙個空的constructor方法會被預設新增。class point ...