认识函数
- 函数的声明使用function关键字:
函数必须调用才会执行
// 声明一个名为 sayHello 的函数
function sayHello() {
console.log('hello my name is www');
}
sayHello() // 调用函数
// 函数表达式允许省略函数名
var foo = function() {
console.log('我是foo函数')
}
foo()
- 函数的参数
// name,age称为函数的参数(形参parameter)
function info(name, age) {
console.log(`我叫 ${name}`);
console.log(`我的年龄是 ${age}`);
}
info('www',19) // www,19称之为函数的实参(argument)
-
函数的返回值:
使用return关键字来返回结果- 一旦在函数中执行return操作,那么当前函数会终止
- 如果没有使用 return语句 ,那么函数有默认的返回undefined
- 如果使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
-
arguments对象
- arguments对象是所有(非箭头)函数中都可用的局部变量
- 该对象中存放着所有的调用者传入的参数,从0位置开始,依次存放
- arguments变量的类型是一个object类型,和数组的用法看起来很相似
// arguments的实例
function sum() {
var total = 0
for (var i = 0;i < arguments.length; i++) total += i
return total
}
sum(21,34)
sum(54,23,24)
- 函数的练习
// 练习一:定义一个函数,传入宽高,计算矩形区域的面积
function getRectangleArea(width, height) {
return width * height
}
var area1 = getRectangleArea(4,5)
// 练习二:传入半径,计算圆形的面积
function getCircleArea(radius) {
return Math.PI * radius * radius
}
var rear2 = getCircleArea(10)
// 练习三:传入n(n为正整数),计算1~n数字的和
function sumN(num) {
if(num <= 0){
alert('请传入正整数')
return
}
var total = 0
for (var i = 1; i <= num; i++) total += i
return total
}
var result = sumN(3)
// 联系四:传入一个数字,可以根据数字转化成显示为 亿、万文字显示的文本(例如播放量)
function formatCount(count) {
if(count >= 10_0000_0000){
count = Math.floor(count / 10_0000_0000) + '亿' // Math.floor()向下取整
}else if(count >= 10_0000){
count = Math.ceil(count / 10_0000) + '万' // Math.ceil()向下取整
}else {
count = count
}
return count
}
formatCount(24354523457);
函数的递归
// 函数内部是可以调用另外一个函数的
function foo() {
console.log('我是foo函数');
}
function baz() {
console.log('我是baz函数');
foo()
}
baz()
// 当函数调用了自己本身的函数,就称之为 '递归',必须要有结束条件,否则会产生无限调用,造成报错
function baz() {
console.log('我是baz函数');
baz()
}
baz()
例子一:实现一个自己的幂函数pow,x的y次方
// 实现一:Math对象中的pwo方法
Math.pow(2, 3)
// 实现二:**是es7才出现的操作符
function pow1(x, y) {
return x ** y
}
// 自己实现一:for循环的实现
function pow2(x, y) {
var result = 1
for (var i = 0; i < y; i++) {
result *= x
}
return result
}
// 自己实现二:递归的实现
function pow(x, y) {
if (y === 1) return x
let foo = x * pow(x, y - 1)
console.log(foo, 'foo');
return foo
}
pow(2, 5);
例子二:实现斐波那契数列
// 数列:1 1 2 3 5 8 13 21 55...
// 位置:1 2 3 4 5 6 7 8 9 10...
// 递归实现
function fibonacci(n) {
if (n === 1 || n === 2) return n
return fibonacci(n - 1) + fibonacci(n - 2)
}
// for实现
function fibonacci(n) {
if (n === 1 || n === 2) return n
var n1 = 1
var n2 = 1
var result = 0
for (var i = 3; i <= n; i++) {
result = n1 + n2
n1 = n2
n2 = result
}
return result
}
局部变量和外部变量
作用域表示一些标识符的作用有效范围
函数的作用域表示在函数内部定义的变量,只有在函数内部可以被访问到
- 定义在函数内部的变量,被称之为局部变量
- 定义在函数外部的变量,被称之为外部变量
- 在函数之外声明的变量(在script中声明的),称之为全局变量
变量的查找顺序:优先访问自己函数中的变量,没有找到时,在外部中访问
头等函数
函数可以作为别的
函数的参数、函数的返回值,赋值给变量或存储在数据结构中
- 函数可以在变量和变量之间相互进行赋值
var foo1 = function() {
console.log('我是foo1函数')
}
var foo2 = foo1
foo2()
- 函数可以作为另一个函数的参数
var foo1 = function() {
console.log('我是foo1函数')
}
function bar(fn) {
console.log('fn:', fn)
fn()
}
bar(foo1)
- 函数作为另一个函数的返回值
function sayHello(name) {
function hi() {
console.log('hi' + name)
}
return hi
}
var fn = sayHello('www') // 柯里化
fn()
- 将函数存储在另一个函数中
var obj = {
name:'www',
eating:function() {
console.log('我是eating函数')
}
}
boj.eating()
function bar1() {
console.log('我是bar1函数')
}
function bar2() {
console.log('我是bar2函数')
}
var fns = [bar1,bar2]
回调函数
function foo(fn) {
// 通过fn去调用bar函数的过程,称之为函数的回调
fn()
}
function bar() {
console.log('bar函数被执行了')
}
foo(bar) // 执行foo函数,将bar以参数的形式传给foo
例子:
// 回调函数的案例
function request(url,callBack) {
console.log('根据url向服务器发送请求');
console.log('需要花费比较长的时间拿到结果');
var list = [1,2,3,231]
callBack(list)
}
function handleResult(res) {
console.log('在handleResult中拿到结果',res);
}
request('www.baidu.com',handleResult)
// 回调函数案例的重构,
// 传入的函数没有名字,也没有对应的变量(匿名函数)
request('www.bai.com',function (res) {
console.log('在handleResult中拿到结果',res);
})
立即执行函数(了解)
会创建一个独立的执行上下文环境,可以避免外界访问或修改内部的变量,也避免了对内部变量的修改
// 匿名函数声明
(function baz() {
console.log('我是baz函数');
})();
// 匿名函数其他写法
+ function foo() {
console.log('立即执行foo函数');
}();
(function() {
console.log('立即执行函数');
}())
立即执行函数应用
<button class="btn">按钮1 </button>
<button class="btn">按钮2 </button>
<button class="btn">按钮3 </button>
var btns = document.querySelectorAll('.btn')
for (var i = 0;i <= btns.length; i++){
(function (m) {
btn[m].onclick = function () {
console.log(`按钮点击了${m+1}按钮`);
}
})(i)
}