JavaScript 的函数
函数的基本概念
在JavaScript中,每个函数其实都是一个Function对象。---mdn
JavaScript 函数通过function
关键词进行定义,其后是函数名和括号 ()。
- 函数()内包含参数
- 由函数执行的代码被放置在花括号中:{}
以下为一个典型的函数. - 函数参数(Function parameters)是在函数定义中所列的名称,一个函数最多有255个参数.
function name(参数 1, 参数 2, 参数 3) {
要执行的代码
}
当申明一个函数时,函数并不会执行.只有当函数被调用时,函数才会执行
声明函数
函数有两种申明方式
普通函数声明
function sayHellow(name) {
console.log ("hellow" + name)
}
sayHellow("gundam")
最后输出: “hello gundam”
函数表达式
函数本身就是一个值,把这个值赋值给这个变量.最后调用这个变量.
const sayHellow = function (name) {
console.log ("hellow" + name)
}
sayHellow("gundam")
参数
形参
申明时,可以设置函数的形参
- 以下代码中 . 括号()内的
number,color
就是形参. - 当调用这个函数时,就可以传递这个参数.
zaku()
内的"006","red"
就是实际参数,实参.
function zaku(number,color) {
console.log(number)
console.log(color)
}
zaku ("006","red")
arguments对象
使用arguments对象获取到该函数的所有传入参数(获取这个函数的传递的是所有实际参数)
- arguments是指代我真正传递的参数.
function zaku(number,color) {
console.log(number)
console.log(color)
console.log(arguments)
console.log(arguments[0])
console.log(arguments.length)
console.log(arguments[1] === "red")
}
zaku("006","red")
输出
举个例子
function zaku() {
console.log(arguments[2]+arguments[0]+arguments[4]+arguments[1])
}//根据arguments序号指代文字输出"红色有角三倍速夏亚"
zaku("有角 ","夏亚","红色 ","god","三倍速 ")
返回值return
- 使用return把结果导出
- 函数执行到return就立刻停止.不会再执行return后面的内容
- 如果没有设置return,则该函数执行后的结果就是undefind
function zaku(a,b) {
return a+b
}
console.log(zaku("红色","有角 "))
关于return和conso.log的区别
- 和
console.log
有很大的区别.console.log
是把变量的值展示在控制台,只是展示. - 而return是把函数的值拿出来.得到结果,可以赋值给变量.
- 以下代码中,先调用函数,给函数设置实际参数,然后函数执行,在控制台展示3,4
- 然后在控制台展示变量a,而a是函数zaku(3,4)的值,函数zaku()返回的值是console.log(a,b)本身,因为console.log(a,b)本身就是undefined,因此展示undefined
function zaku(a,b) {
return console.log(a,b)
}
let a = zaku(3,4)//调用函数,在调试台展示a,b.
console.log(a)//return console.log(3,4)的返回值,console.log(3,4)的返回值是undefined
箭头函数
- 箭头函数简化函数表达式
let 变量= 名称=> 执行代码
let sum = (a,b) => a + b
console.log (sum(3,4))//控制台输出7
const fn = name => 'Hello ' + name
// 等价于
const fn = function(name) { } return 'Hello' + name
// 多个参数
const sum = (a, b) => a + b
const sumOfSquares = arr => {
let result = 0
for(let v in arr) {
} result += v**2
} return result
const add = a => b => a + b
add(3)(4)
声明前置
声明的函数function(){}
和var
会在系统初始化之前提前至最上层.
js会在运行时,将文件内所有的函数声明和声明变量,都提升到文件最顶部,这样你可以在代码任意位置访问这个函数。对于var声明变量,在函数内部运行时同理.
var 的声明前置
- 对于
let
声明的变量,我们不可以在初始化之前去使用它 - 但是对于
var
声明的变量,初始化之前系统会自动将var提前至最顶层.
a=3 console.log(a) var a
function doSomething() {
console.log(b)
var b = 10
} console.log(b)
function声明前置
并不是所有的函数声明都会被前置.普通的函数声明
会前置,而函数表达式
不会前置
fn()
function fn() {
} console.log('Hello jirengu.com')
fn2() //会报错,函数表达式不会前置
const fn2 = function() { console.log('fn2') }
函数的运行环境
- 全局作用域/全局环境
- 函数作用域/函数环境
console.log('in 全局 start')// ①
foo()
console.log('in 全局 end') //④
function foo() {
console.log('in foo')//②先进入foo()函数输出in foo
bar()
function bar() {
console.log('in bar')//③在进入bar(函数),输出in bar
}
}
作用域链
步骤是这样的:
- 函数在执行过程中,先从内部寻找变量.
- 如果找不到,再从创建当前函数所在的作用域(词法作用域)去找, 以此往上,直到全局作用域.
- 注意找的是变量的此刻的状态.
- 不管函数在哪里调用,这个函数在哪声明的,就去哪里寻找他变量.
例1
let a = 0
function foo(){
let a = 1
bar()//
}
function bar(){
console.log(a)//自身没有设置a变量,从函数声明的位置全局位置寻找变量.a=0
a=5//上一步执行完成后,全局变量a变成5.
}
foo()
console.log(a)
因此,调试台应当输出0,5
例2
let a = 0
function foo(){
let a= 1
bar()
function bar (){
console.log(a)//自身作用域没有声明变量,上一级存在声明变量a=1,因此a=1.
a=5//上一步执行完成后,将上一级的作用域中a赋予值5
}
}
foo()
console.log(a)//全局作用域a=0
因此,代码输出为1,0
例3
let a = 0
function foo(){
bar()
var a = 1
function bar (){
console.log(a)//函数内js按照顺序执行,①var a②bar() ③a=1.因此函数bar()使用未被赋值的val a.
}
}
foo()
因为a=1赋值是在函数bar()后面,因此bar使用未被赋值的a.因此,consol.log输出defined
立即执行的函数表达式
- 先声明一个函数,然后立即执行他
- 方便隔离作用域,做调试挺方便的
(function(){
//这里写函数体
})()
递归 (套娃)
在函数里面套函数,就像套娃一样