JS基础-函数

115 阅读5分钟

认识函数

  • 函数的声明使用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)  
}