函數的聲明方式:
function fn(){} //具名函數
var f = function (){} //匿名函數,必須將其賦給一個變量,這種形式稱為函數表達式
var f = fucntion fn(){} //具名函數,函數表達式
var f = new Function('x', 'y', 'return x+y') //構造函數聲明,最不常用
var f = ()=>{} //箭頭函數
//對于var f = fucntion fn(){}這種形式的,只能通過f()調用
var f = function fn(){console.log('hello')}
fn() //報錯
f() //hello
函數的本質
請看下面代碼
//這是一個求三角形面積的函數
function area (width, height){
s = width*hegiht.2
return s
}
當我們每次需要求三角形面積的時候,調用這個函數即可,需要就用
所以,函數的本質就是可以反復調用的代碼塊,并且可以接受參數,結果會根據參數的不同而改變
this、arguments
this表示屬性當前所在的對象
var obj = {
n: 1,
fn: function(){
console.log(this.n)
}
}
obj.fn() //1
obj.fn,call(obj) //1
obj.fn.call() //undefined
var n = 2
obj.fn.call() //2
call可以改變this的指向,this就是call的第一個參數,在非嚴格模式下,call的第一個參數為空或為undefined,this默認指向window
function fn(){
console.log(this)
console.log(this === window)
}
fn.call()
//Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …}
//true
在嚴格模式下,call的第一個參數是什么this就是什么
function fn(){
'use strict'
console.log(this)
console.log(this === window)
}
fn.call()
//undefined
//false
fn.call(123)
//123
//false
arguments就是函數接收的參數,是一個偽數組,因為它的原型鏈沒有Array.prototype這一環
function f(){
console.log(arguments)
}
fn(1,2,3,4) //Arguments(4) [1, 2, 3, 4, callee: ?, Symbol(Symbol.iterator): ?]
作用域、變量提升
每個函數都有自己單獨的作用域,并且在函數內部也會發生變量提升。
函數內部的變量提升
- var命令聲明的變量,不管在什么位置,變量聲明都會被提升到函數體的頭部
函數作用域問題
- 若一個函數內部有子函數,代碼如下
var a = 1
function f1(){
var a = 2
console.log(a) //優先在f1范圍內查找a,若找不到a向上查找(也就是全局范圍),不會想下查找
f2()
function f2(){
var a = 3
console.log(a)
}
}
f1() //2 3
console.log(a) //1
此時的作用域是這樣的:
image.png