1.變量作用域
1.如果一個(gè)變量在函數(shù)體內(nèi)部聲明,則該變量的作用域?yàn)檎麄€(gè)函數(shù)體充岛,函數(shù)體外不可引用访诱。
var add = function(){
var a = 1;
}
a+1; // ReferenceError
2.如果兩個(gè)函數(shù)各自聲明了同一個(gè)變量麻蹋,那么該變量只在各自的函數(shù)體內(nèi)起作用。
var foo(){
var a = 1;
console.log(a); ?//1
}
var bar(){
var a= 'A';
console.log(a); // A
}
3.由于js函數(shù)可以嵌套街夭,此時(shí)砰碴,內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)定義的變量,反過(guò)來(lái)不可以
function outside(){
var outside = 1;
? ? function inside(){
? ? ? ? var inside = 2;
? ? ? ? var add = outside + inside; ? ?//3
? ? ? ? console.log(add); ?
}
? ? ? ?console.log(add); ? // ? referenceError
}
4.如果外部函數(shù)和內(nèi)部函數(shù)重名莱坎,內(nèi)部函數(shù)變量會(huì)覆蓋外部函數(shù)的變量
function out(){
var a = 1;
? ? function in (){
? ? var a = 2;
? ? console.log(a); ?// 2
}
in();
console.log(a); ?
}
2.變量提升
js會(huì)把所有變量的聲明提前到函數(shù)頂部
變量提升和函數(shù)提升是js設(shè)計(jì)缺陷衣式,在其他語(yǔ)言中直接就報(bào)錯(cuò)了
不要使用變量提升與函數(shù)聲明提升,所有變量和函數(shù)遵循先聲明后使用的原則
不要在JS的設(shè)計(jì)缺陷中糾結(jié)檐什,知道后避開(kāi)坑 ?---廖雪峰
3.全局作用域
不在任何一個(gè)函數(shù)內(nèi)定義的變量就具有全局作用域碴卧。實(shí)際上,js有一個(gè)默認(rèn)的全局對(duì)象window乃正,全局作用域的對(duì)象實(shí)際上是綁定到window的一個(gè)屬性住册。
var course = "learn js";
alert(course); ? ?
alert(window.course);
js實(shí)際上只有一個(gè)全局作用域,任何變量(函數(shù)也是),如果沒(méi)有在當(dāng)前的函數(shù)作用域中找到瓮具,就會(huì)繼續(xù)向上查找荧飞,最后如果全局作用域也沒(méi)有找到凡人,則報(bào)ReferenceError.
4.局部作用域
js變量的作用域?qū)嶋H上是函數(shù)的內(nèi)部,在for循環(huán)語(yǔ)句中是無(wú)法定義具有局部作用域的變量:
function foo(){
? ? for(var i = 0;i<100;i++){
? ? ? ? //
? ? }
? ? i+=100; ? //仍然可以引用變量i
}
為了解決塊級(jí)作用域叹阔,ES6引入了新的關(guān)鍵字let,可以聲明一個(gè)塊級(jí)作用域挠轴。
function foo(){
var sum =0;
for(let i=0; i<100; i++) {
? ? ? ? sum += i;?
? ?}?
? i +=1; ?// ReferenceError
}
5常量
在ES6之前,通常用全部大寫(xiě)的變量表示這是一個(gè)常量耳幢,不可修改值岸晦。
var PI = 3.14;
ES6中引入了新的關(guān)鍵字const來(lái)定義常量,const與let都具有塊級(jí)作用域睛藻。
const PI = 3.14
常量一旦聲明启上,不可修改
const(var) ?PI = 3.14;
PI = 3;
console.log(PI); ? ?//chrome報(bào)錯(cuò) ? Identifier 'PI' has already been declared