1、兩個(gè)不同的函數(shù)各自申明了同一個(gè)變量,那么該變量只在各自的函數(shù)體內(nèi)起作用。
2、由于JavaScript的函數(shù)可以嵌套,此時(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)塊級(jí)作用域。
6、ES6中,表示常量的const也有塊級(jí)作用域
7、ES6解構(gòu):一個(gè)對(duì)象中取出若干屬性,一個(gè)數(shù)組中取出若干到元素
8、map():給數(shù)組的每一項(xiàng)進(jìn)行相同的操作,得到一個(gè)新數(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個(gè)參數(shù):callback(currentValue, index, array),通常我們僅需要第一個(gè)參數(shù),而忽略了傳入的后面兩個(gè)參數(shù)。不幸的是,parseInt(string, radix)沒有忽略第二個(gè)參數(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ù)僅接收一個(gè)參數(shù)。
9、reduce() : 把一個(gè)函數(shù)作用在一個(gè)Array的 [ x1, x2, x3... ] 上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce()把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算
a ) 對(duì)一個(gè)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()也能派上用場(chǎng):
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() 會(huì)改變?cè)瓟?shù)組
12、閉包實(shí)例1:
function outter(){
var sky="blue";
function inner(){
console.log(sky);
}
return inner;
}
var result=outter();
result(); //"blue"
閉包:
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個(gè)函數(shù)內(nèi)創(chuàng)建另一個(gè)函數(shù),通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量,利用閉包可以突破作用鏈域,將函數(shù)內(nèi)部的變量和方法傳遞到外部。
閉包的特性:
1.函數(shù)內(nèi)再嵌套函數(shù)
2.內(nèi)部函數(shù)可以引用外層的參數(shù)和變量
3.參數(shù)和變量不會(huì)被垃圾回收機(jī)制回收
上面代碼就包含一個(gè)簡(jiǎn)單的閉包:outter函數(shù)的返回值是一個(gè)函數(shù),即inner。inner在outter內(nèi)部,理所當(dāng)然能訪問到局部變量sky,但當(dāng)inner作為outter的返回值賦給outter外的全局變量時(shí),神奇的事情發(fā)生了:在全局作用域中訪問到了sky,這就是閉包。
原理:
每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)一個(gè)函數(shù)被執(zhí)行時(shí),它的執(zhí)行環(huán)境就會(huì)被推入環(huán)境棧,其活動(dòng)對(duì)象(存儲(chǔ)環(huán)境中定義的變量及函數(shù))加入作用域鏈中,一旦函數(shù)執(zhí)行完,棧將其環(huán)境彈出,活動(dòng)對(duì)象被銷毀。·
對(duì)于上面的例子來說,outter執(zhí)行完之后將返回inner給了result,outter的執(zhí)行環(huán)境從環(huán)境棧彈出,控制權(quán)交給全局環(huán)境,outter的活動(dòng)對(duì)象理應(yīng)被銷毀。但此時(shí)inner已經(jīng)存儲(chǔ)在全局活動(dòng)對(duì)象中了,同時(shí)inner需要訪問sky,所以outter的活動(dòng)對(duì)象沒有被銷毀,即使result執(zhí)行完畢,outter的活動(dòng)對(duì)象依然存在于作用域鏈中,只有當(dāng)result被銷毀
閉包優(yōu)點(diǎn):
能在一個(gè)函數(shù)外訪問函數(shù)中的局部變量,把這些變量用閉包的形式放在函數(shù)中便能避免全局作用域污染。
閉包缺點(diǎn):
- 閉包將函數(shù)的活動(dòng)對(duì)象維持在內(nèi)存中,過度使用閉包會(huì)導(dǎo)致內(nèi)存占用過多;
- 閉包只能取得外部函數(shù)中任何變量的最后一個(gè)值,在使用循環(huán)且返回的函數(shù)中帶有循環(huán)變量時(shí)會(huì)得到錯(cuò)誤結(jié)果;
- 當(dāng)返回的函數(shù)為匿名函數(shù)時(shí),注意匿名函數(shù)中的this指的是window對(duì)象。
function counter () {
var n = 0;
return {
count:function(){return n++;},
reset:function(){n = 0;}
}
}
var c = counter();
var d = counter(); // 每創(chuàng)建一個(gè)實(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、定時(shí)器setTimeout setInterval以及回調(diào)函數(shù)
當(dāng)不需要setInterval或者setTimeout時(shí),定時(shí)器沒有被clear,定時(shí)器的回調(diào)函數(shù)以及內(nèi)部依賴的變量都不能被回收,造成內(nèi)存泄漏。
比如:vue使用了定時(shí)器,需要在beforeDestroy 中做對(duì)應(yīng)銷毀處理。js也是一樣的。