1、兩個不同的函數(shù)各自申明了同一個變量嘶居,那么該變量只在各自的函數(shù)體內(nèi)起作用。
2、由于JavaScript的函數(shù)可以嵌套奖地,此時,內(nèi)部函數(shù)可以訪問外部函數(shù)定義的變量羹铅,反過來則不行香缺。
3、變量提升苫幢,
4访诱、全局作用域( window )
5、局部作用域:for if else 不能創(chuàng)造作用域
eg:for循環(huán)中用var定義的i韩肝,在for循環(huán)外部触菜,依舊能夠訪問到;相反哀峻,用 let 可以實(shí)現(xiàn)塊級作用域涡相。
6、ES6中剩蟀,表示常量的const也有塊級作用域
7催蝗、ES6解構(gòu):一個對象中取出若干屬性,一個數(shù)組中取出若干到元素
8育特、map():給數(shù)組的每一項(xiàng)進(jìn)行相同的操作丙号,得到一個新數(shù)組,是操作后得到的數(shù)組
把Array的所有數(shù)字轉(zhuǎn)為字符串:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
·
字符串轉(zhuǎn)成數(shù)字為什么不行缰冤?
var arr = ['1', '2', '3'];
arr.map(parseInt); // 1,NaN,NaN
正確解析:
由于map()接收的回調(diào)函數(shù)可以有3個參數(shù):callback(currentValue, index, array)犬缨,通常我們僅需要第一個參數(shù),而忽略了傳入的后面兩個參數(shù)棉浸。不幸的是怀薛,parseInt(string, radix)沒有忽略第二個參數(shù),導(dǎo)致實(shí)際執(zhí)行的函數(shù)分別是:
parseInt('0', 0); // 0, 按十進(jìn)制轉(zhuǎn)換
parseInt('1', 1); // NaN, 沒有一進(jìn)制
parseInt('2', 2); // NaN, 按二進(jìn)制轉(zhuǎn)換不允許出現(xiàn)2
可以改為:
arr.map(Number);
因?yàn)镹umber(value)函數(shù)僅接收一個參數(shù)涮拗。
9乾戏、reduce() : 把一個函數(shù)作用在一個Array的 [ x1, x2, x3... ] 上,這個函數(shù)必須接收兩個參數(shù)三热,reduce()把結(jié)果繼續(xù)和序列的下一個元素做累積計算
a ) 對一個Array求和鼓择,就可以用reduce實(shí)現(xiàn):
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
b) 要把[1, 3, 5, 7, 9]變換成整數(shù)13579,reduce()也能派上用場:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x * 10 + y;
}); // 13579
10就漾、filter() : 從數(shù)組中呐能,篩選出想要的數(shù)據(jù),返回組成新的數(shù)組
a) 數(shù)組去重
arr.filter( function(element,index,self){
return self.indexOf(element) === index
} )
11、sort():默認(rèn)轉(zhuǎn)成字符串后摆出,再進(jìn)行比較朗徊。導(dǎo)致 [1,2,10,20] 的排序結(jié)果為【1,10偎漫,2爷恳,20】,解決如下:
arr.sort(function(x,y){
if(x>y){
return 1;
} else if(x==y){
return 0;
} else{
return -1;
}
})
并且象踊,sort() 會改變原數(shù)組
12温亲、閉包實(shí)例1:
function outter(){
var sky="blue";
function inner(){
console.log(sky);
}
return inner;
}
var result=outter();
result(); //"blue"
閉包:
閉包是指有權(quán)訪問另一個函數(shù)作用域中變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個函數(shù)內(nèi)創(chuàng)建另一個函數(shù)杯矩,通過另一個函數(shù)訪問這個函數(shù)的局部變量,利用閉包可以突破作用鏈域栈虚,將函數(shù)內(nèi)部的變量和方法傳遞到外部。
閉包的特性:
1.函數(shù)內(nèi)再嵌套函數(shù)
2.內(nèi)部函數(shù)可以引用外層的參數(shù)和變量
3.參數(shù)和變量不會被垃圾回收機(jī)制回收
上面代碼就包含一個簡單的閉包:outter函數(shù)的返回值是一個函數(shù)史隆,即inner魂务。inner在outter內(nèi)部,理所當(dāng)然能訪問到局部變量sky泌射,但當(dāng)inner作為outter的返回值賦給outter外的全局變量時粘姜,神奇的事情發(fā)生了:在全局作用域中訪問到了sky,這就是閉包熔酷。
原理:
每個函數(shù)都有自己的執(zhí)行環(huán)境相艇,當(dāng)一個函數(shù)被執(zhí)行時,它的執(zhí)行環(huán)境就會被推入環(huán)境棧纯陨,其活動對象(存儲環(huán)境中定義的變量及函數(shù))加入作用域鏈中坛芽,一旦函數(shù)執(zhí)行完,棧將其環(huán)境彈出翼抠,活動對象被銷毀咙轩。·
對于上面的例子來說,outter執(zhí)行完之后將返回inner給了result阴颖,outter的執(zhí)行環(huán)境從環(huán)境棧彈出活喊,控制權(quán)交給全局環(huán)境,outter的活動對象理應(yīng)被銷毀量愧。但此時inner已經(jīng)存儲在全局活動對象中了钾菊,同時inner需要訪問sky,所以outter的活動對象沒有被銷毀偎肃,即使result執(zhí)行完畢煞烫,outter的活動對象依然存在于作用域鏈中,只有當(dāng)result被銷毀
閉包優(yōu)點(diǎn):
能在一個函數(shù)外訪問函數(shù)中的局部變量累颂,把這些變量用閉包的形式放在函數(shù)中便能避免全局作用域污染滞详。
閉包缺點(diǎn):
- 閉包將函數(shù)的活動對象維持在內(nèi)存中凛俱,過度使用閉包會導(dǎo)致內(nèi)存占用過多;
- 閉包只能取得外部函數(shù)中任何變量的最后一個值料饥,在使用循環(huán)且返回的函數(shù)中帶有循環(huán)變量時會得到錯誤結(jié)果蒲犬;
- 當(dāng)返回的函數(shù)為匿名函數(shù)時,注意匿名函數(shù)中的this指的是window對象岸啡。
function counter () {
var n = 0;
return {
count:function(){return n++;},
reset:function(){n = 0;}
}
}
var c = counter();
var d = counter(); // 每創(chuàng)建一個實(shí)例原叮,他們的n都互不影響
c.count() //0
d.count() //0
c.reset() //reset()和count()共享
d.count() //1
c.count() //0
<script>
function A(){
var x = 1;
return function(){
x++;
console.log(x);
}
}
var m1 = A();//第一次執(zhí)行A函數(shù)
m1();//2
m1();//3
var m2 = A();//第二次執(zhí)行A函數(shù)
m2();//2
m1();//4
</script>
常見的內(nèi)存泄漏方式:
1、意外的全局變量
a)函數(shù)里未用var/let來聲明變量
b)在函數(shù)中通過this賦予變量巡蘸,在函數(shù)中篇裁,this指向window
2、定時器setTimeout setInterval以及回調(diào)函數(shù)
當(dāng)不需要setInterval或者setTimeout時赡若,定時器沒有被clear,定時器的回調(diào)函數(shù)以及內(nèi)部依賴的變量都不能被回收团甲,造成內(nèi)存泄漏逾冬。
比如:vue使用了定時器,需要在beforeDestroy 中做對應(yīng)銷毀處理躺苦。js也是一樣的身腻。