1.函數(shù)聲明
JavaScript函數(shù)有匿名函數(shù)解虱、具名函數(shù)和箭頭函數(shù)三種攘须。
匿名函數(shù)
let fn = function () {
return 1
} //引用匿名函數(shù)的地址
let fn2 = fn //引用匿名函數(shù)地址
console.log(fn.name) //fn
console.log(fn2.name) //fn
函數(shù)就是對象漆撞,對象存在堆內(nèi)存里面殴泰。匿名函數(shù)的函數(shù)名就是引用它的變量的名字。
具名函數(shù)
function fn3() {
return 3
}
console.log(fn3.name) //fn3
let fn5 = function fn4() {
return 4
}
console.log(fn4.name) //Uncaught ReferenceError: fn4 is not defined
console.log(fn5.name) //fn4
fn3的作用域的全局浮驳,fn5引用了fn4悍汛,所以fn4的作用域是函數(shù)本身。
箭頭函數(shù)
let fn6 = i => i + 1 //一個參數(shù)寫法
let fn7 = (i, j) => { //多個參數(shù)寫法
console.log(i, j)
return i + j;
}
箭頭函數(shù)沒有name至会,但是箭頭函數(shù)沒有this
2.詞法作用域(靜態(tài)作用域)
靜態(tài)作用域又叫做詞法作用域离咐,采用詞法作用域的變量叫詞法變量。詞法變量有一個在編譯時靜態(tài)確定的作用域奉件。詞法變量的作用域可以是一個函數(shù)或一段代碼宵蛀,該變量在這段代碼區(qū)域內(nèi)可見(visibility);在這段區(qū)域以外該變量不可見(或無法訪問)县貌。詞法作用域里术陶,取變量的值時,會檢查函數(shù)定義時的文本環(huán)境煤痕,捕捉函數(shù)定義時對該變量的綁定梧宫。【維基百科】
var global1 = 1 //全局變量
function fn1(param1){
var local1 = 'local1' //局部變量
var local2 = 'local2' //局部變量
function fn2(param2){
var local2 = 'inner local2' //局部變量
console.log(local1)
console.log(local2)
}
function fn3(){
var local2 = 'fn3 local2' //局部變量
fn2(local2)
}
fn2()
//local1
//inner local2
fn3()
//local1
//inner local2
}
fn1()
詞法樹只能確定變量的關(guān)系摆碉,不能確定變量的值塘匣。
3.this和arguments
this 就是 call 的第一個參數(shù)!call 的其他參數(shù)統(tǒng)稱為 arguments
call才是正常的函數(shù)調(diào)用巷帝,其他調(diào)用函數(shù)的方式都是語法糖忌卤。
function f(){
console.log(this)
console.log(arguments)
}
f.call() // window,相當(dāng)于f.call(undefined)
f.call({name:'frank'}) // {name: 'frank'}, []
f.call({name:'frank'},1) // {name: 'frank'}, [1]
f.call({name:'frank'},1,2) // {name: 'frank'}, [1,2]
this 是隱藏的第一個參數(shù),且一般是對象楞泼,用于占位驰徊。arguments是偽數(shù)組历谍,第二到最后一個參數(shù)都放里面,如果只有一個參數(shù)就為[]辣垒。
4.call望侈、apply和bind
fn.call(asThis, p1,p2) 是函數(shù)的正常調(diào)用方式
當(dāng)你不確定參數(shù)的個數(shù)時,就使用 apply
fn.apply(asThis, params)
call 和 apply 是直接調(diào)用函數(shù)勋桶,而 bind 則是返回一個新函數(shù)(并沒有調(diào)用原來的函數(shù))脱衙,這個新函數(shù)會 call 原來的函數(shù),call 的參數(shù)由你指定例驹。
5.函數(shù)柯里化
函數(shù)柯里化就是只傳遞給函數(shù)一部分參數(shù)來調(diào)用它捐韩,讓它返回一個函數(shù)去處理剩下的參數(shù)。(返回函數(shù)的函數(shù))
//柯里化之前
function sum(x,y){
return x+y
}
//柯里化之后
function addOne(y){
return sum(1, y)
}
//柯里化之前
function Handlebar(template, data){
return template.replace('{{name}}', data.name)
}
//柯里化之后
function Handlebar(template){
return function(data){
return template.replace('{{name}}', data.name)
}
}
6.高階函數(shù)
在數(shù)學(xué)和計算機科學(xué)中鹃锈,高階函數(shù)是至少滿足下列一個條件的函數(shù):
a.接受一個或多個函數(shù)作為輸入:forEach sort map filter reduce,
b.輸出一個函數(shù):lodash.curry,
c.不過它也可以同時滿足兩個條件:Function.prototype.bind
7.回調(diào)函數(shù)
被當(dāng)做參數(shù)的函數(shù)就是回調(diào)函數(shù)(調(diào)用這個回調(diào))荤胁,回調(diào)跟異步?jīng)]有任何關(guān)系。
//同步回調(diào)
array.sort.call(array, fn)
array.forEach.call(array, fn)
array.map.call(array, fn)
array.filter.call(array, fn)
array.reduce.call(array, fn)
//異步回調(diào)
setTimeout(fn, 1000)
8.構(gòu)造函數(shù)
返回對象的函數(shù)就是構(gòu)造函數(shù)屎债,一般首字母大寫仅政。
new Number(1)
new String('s')
function Empty(){
this.name = 'null'
return this
}
var empty = new Empty //Empty.call({})