JS函数

函数(方法):

通过function关键字声明函数;函数必须被调用才能执行

1.无参函数

//name是自定义的函数名遵循变量的命名规则
function name(){
	//函数体:
}

调用执行函数:

通过 函数名( ) 调用执行函数

2.有参函数

参数个数不受限制

function name(arg1, arg2, ...){
    // arg1, arg2, ...  这是参数, 称之为形参, 本质是变量
    // 函数体
}

调用执行函数:

通过 函数名(value1,value2,...) 调用执行函数value1,value2,...这是实参

3.函数的声明

无参函数

function print(){
    // 进行相关的逻辑处理
    console.log('hello world');
}
// 调用执行函数
print();
//hello world

有参函数

function koujue(a){
    let res = a + 'world';
    console.log(res);
}
//可以调用执行多次
koujue(100);//100world
koujue('hello');//helloworld

4.函数声明方式的区别

  1. 通过function关键字

    function name(){}

    // 关键字声明 :js优先解析函数和变量的声明
    first();
    function first(){
    console.log('关键字function');
     	}
    first();
    
  2. 字面量形式 : 变量名就是函数名

    let name = function(){}
    
    // =========== 字面量形式 
    //  var声明变量的存在变量提升
    console.log(second); // undefined
    //  调用执行函数
    // second(); //  TypeError: second is not a function
    
    var second = function(){
        console.log('字面量');
    }
    second();
    
  3. 调用执行函数:

    name();
    
  4. 一个函数可以被调用执行多次

两种方式的区别:

关键字声明的函数 可以在函数声明前后进行调用;

字面量形式声明的函数,只能在声明后调用

5.形参与实参

形参定义:

函数声明时传入的参数称之为形参

实参定义:

函数调用时传入的参数称之为实参

形参与实参之间的关系:

形参与实参是一一对应的

形参多实参少:

多余的形参默认值是undefined

function print1(a, b, c){
    console.log(a, b, c);
}
print1(100);//100 undefined undefined
print1();//undefined undefined undefined

形参少实参多:

多余的实参会被自动忽略

function print1(a, b, c){
    console.log(a, b, c);
}
print1(100,200,300,400);//100 200 300
print1();//undefined undefined undefined

6.匿名函数🔴

说明:没有指定函数名

示例:

//变量名就是函数名
let f = function(){
    console.log("这是匿名函数");
}
//调用函数
f();// 这是匿名函数

//传入形参
let print = function(a, b){
    console.log(a, b);
}
//传入实参 
print('hello', 100);//hello 100

7.函数的应用(封装函数)

案例一:封装乘法口诀表

封装前:

for(let i = 1; i <= 9; i++){
 for(let j = 1; j <= i; j++){
     document.write(`${j} * ${i} = ${i * j}; &nbsp; &nbsp;`)
 }
 document.write('<br>')

封装后:

function FormulaTable(start, end) {
 for (let i = start; i <= end; i++) {
     for (let j = start; j <= i; j++) {
         document.write(`${j} * ${i} = ${i * j}; &nbsp; &nbsp;`)
       }
       document.write('<br>')
   }
}
FormulaTable(1, 9);
FormulaTable(10, 15);
FormulaTable(20, 30);

案例二:封装阶乘

function factorial(num){
 let res = 1;
   for(let i = 1; i <= num; i++){
       res *= i;
   }
   console.log(res);
}
factorial(5);
factorial(10);
factorial(20);

案例三:求连续区间的阶乘之和

function factorialSum(start, end){
    let sum = 0;
    for(let i = start; i <= end; i++){
        let res = 1;
        for(let j = 1; j <= i; j++){
            res *= j
        }
        sum += res;
    }
    console.log(sum);
}
factorialSum(5, 10)
factorialSum(1, 5)

8.作用域

作用域:分为全局作用域 和局部作用域 , es6 新增 块级作用域

全局作用域:

  1. 在函数的外边声明的变量拥有全局作用域
  2. window对象的属性和方法拥有全局作用域(window 通常被省略)

局部作用域:

在函数内声明的变量拥有局部作用域

⚠️在 if 或 for循环中使用var 声明的变量是全局变量 ;

⚠️如果是 let声明的变量,是块级作用域

if(3 > 2){
    let number = 100;  // 块级作用域
    var str = 'hello world'; //  全局作用域
}

for(let i = 0; i < 5; i++) {
    if(i == 3){
        var count = 100; //  全局作用域
    }
}

9.作用域链🔴

说明:变量的作用域

函数内使用或引用某个变量时,首先从函数内自身进行查找,找到则使用,没有则层层向上进行查找,直到找到为止,如果找到全局都没有找到,则报错

let num = '重磅消息';
function first(){
    let num = 100;
    function second(){
        let num ='hello word';
        function third(){
            let num = '今天周五,明天周六';
            console.log(num);
        }
        third();
    }
    second();
}
first();

10.函数的返回值 return

语法结构:

function 函数名(){
    return 需要返回的结果;
}
函数名();

注意事项:⚠️

  1. 函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名( ) 通过return实现

  2. 只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果

  3. return 后面的代码不会执行

  4. return 只能返回一个值,如果用逗号隔开多个值,以最后一个为准

    function fn(num1,num2){
     return num1,num2;
    }
    conslog.log(fn(1,2));//2
    
  5. 求任意两个数的加减乘除结果

    function getResult(num1, num2) {
        return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
    }
    var re = getResult(8, 4);
    console.log(re);
    //[ 12, 4, 32, 2 ]
    
  6. 函数如果有return 则返回的是 return 后面的值,如果函数没有return 则返回undefined

    function fn1(){
        return 666;
    }
    console.log(fn1());// 666
    
    function fn2(){
        
    }
    console.log(fn2()); //undefined
    
  7. break,continue,return 的区别

    • break:结束当前的循环体(如for , while)
    • continue : 跳出本次循环,继续执行下次循环(如for , while)
    • return :不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码

示例:

function getResult(){
    return 666;
}
console.log(getResult()); 
// 666
function getSum(num1,num2){
    return num1 + num2;
}
console.log(getSum(5,6));//11

利用函数求任意一个数组中的最大值

function getArrMax(arr){
    var max = arr[0];
    for(var i = 1;i < arr.length; i++){
        if(arr[i] > max){
            max = arr[i];
        }
    }
    return max;
}
var res = getArrMax([5,2,55,78,13,99]);
console.log(res);

11.函数作为返回值🔴

function print(){
    let str = 'hello';
    return function(){
        console.log('这是返回值',str);
    }
}
print()()

12.变量的提升机制

  1. 在函数内没有使用关键字声明的变量,拥有全局作用域
function first() {
    var count = 200;
    // 没有关键字声明str 
    str = 'hello world';
    console.log(count);
}
first(); // 200
console.log(count); //报错
console.log(str);// hello world
  1. 变量的提升
function second(){
    // 第一个拆分模块
    // var score;
    console.log(score);//undefined
    // 使用关键字var声明的变量会存在变量提升机制
    // 变量的声明会被提升到函数的最上边;变量的赋值还留在原来的位置
    // 这一行代码被拆分两行代码执行
    var score =98;
    // 第二个拆分
    // score = 98;
    console.log(score);//98
}
second();
  1. js 代码 按照从上到下的顺序依次执行

    console.log(str);  
    //  let 声明的变量不存在变量提升的
    // let str = 'hello'; // Cannot access 'str' before initialization
    var str = 'hello';  // undefined   变量提升
    console.log(str);
    

13.函数对象的方法和属性🔴

函数对象的属性:

length : 形参的个数

arguments 属性:是一个类数组对象;在函数的内部存在一个属性 arguments ;该属性是函数固有的

arguments.length :获取的是实参的个数

function print(a,b){
    // arguments 可以在函数内部直接访问使用
    // 是一个类数组对象:本质是对象,单是可以通过下表访问值
    console.log(arguments);
    //[Arguments] { '0': 100, '1': 200, '2': 300, '3': 400 }
    
    // 获取的是实参的个数
    console.log(arguments.length);
    // 4
    
    // 通过下表访问值
    console.log(arguments[0]);
    // 100
}
print(100,200,300,400);

// length 属性获取形参的个数
let len = print.length;
console.log(len);// 2

函数对象的方法:

call() :调用执行函数,修改this指向,传参是一一罗列的

apply() :调用执行函数,修改this指向,传参是以数组的形式

bind() : 返回的是一个新函数,方法的参数是一一罗列的

bind() 方法创建一个新的函数,在bind()被调用时,这个新函数的 this 被指定为bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用。返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

function third(str,n,m){
    console.log('函数对象的方法',str,n,m);
}
third('hello',100,99);//函数对象的方法 hello 100 99
// call() 参数是一一罗列的
third.call(null,'在这里传参',999,666);//函数对象的方法 在这里传参 999 666
// apply() 参数是以数组的形式传递的
third.apply(null,['数组形式传递',500,'第三']);
//函数对象的方法 数组形式传递 500 第三
//bind()方法的参数是一一罗列的,返回的是一个新函数
third.bind()('在这里传参',999,666);
//函数对象的方法 在这里传参 999 666

函数对象的方法 call() apply() bind() 用法和区别

共同点:
都可以修改this 指向; 也可以传参;
不同点:
call()方法的参数是一一罗列的(一个参数列表)
apply()方法的参数是以数组的形式进行传递的(一个包含多个参数的数组。)
bind() 方法的参数是一一罗列的
call()apply() 可以调用执行函数;bind()方法返回的是一个新函数

14.Math

//求数组中的最大值和最小值
let arr = [23, 3245, 123, 440];
// let max = Math.max(10, 30, 50, 20);
let max = Math.max.apply(null, arr);
// let min = Math.min(10, 30, 50, 20);
let min = Math.min.apply(null, arr);
console.log(max, min);
posted @ 2022-04-10 11:24  秋弦  阅读(42)  评论(0编辑  收藏  举报