JavaScript中的函数

84 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

在js中, 函数也是对象, 是一种特殊的对象, 具备普通对象的所有功能, 例如: 属性

区别于普通对象的是, 函数可以封装一段代码, 在需要的时候, 可以通过调用函数来执行这段代码

创建函数

创建函数有两种方式

第一种函数声明方式

function 函数名([形参1, 形参2, ...]) {

// 函数体

}

第二咱函数表达式方式

对于该方式, 变量名就是函数名

let/var 变量名 = function([形参1, 形参2, ...]) {

// 函数体

}

        // 定义函数
        function func1() {
            console.log('这是一个函数');
        }

        let func2 = function() {
            console.log('这也是一个函数');
        }

调用函数

函数名();

        // 调用函数
        func1();
        func2();

形参和实参

在定义函数, 声明函数体可以使用这几个变量, 对于形参的值, 在调用时都会知道

在调用函数时, 传入具体的实参, 传入的这些实参会相应的赋值给对应的形参

在js中, 在调用函数时, 不会检查实参的类型和个数是否和该函数的形参的类型和个数匹配

如果实参的个数大于形参的个数, 多余的实参将不会使用

如果实参的个数小于形参的个数, 那么没有赋值的形参是undefined

        function func3(x, y) {
            console.log('' + x + ',' + y);
        }

        let  = 1, b = 2, c = 3;
        func3(a) // 1,undefined
        func3(a, b, c) // 1,2

typeof 函数名

该运算符操作的是函数名的话则返回function

console.log(typeof func3); // function

函数的返回值

使用return语句来返回函数的返回值, 当当执行完return语句函数立即退出

  • 如果函数没有return语句, 或者return;是这样的return语句, 则相当于return undefined;
  • 函数的返回值可以是做任意类型, 可以是基本类型, 可以是对象, 也可以是函数
        function func4() {
            console.log('这是一个没有return语句的函数');
        }

        function func5() {
            console.log('这是一个有return语句的函数');
            return;
            console.log('这是一个有return语句后面的语句');
        }

        // 返回值为基本类型的函数
        function func6(a, b) {
            return a + b
        }

        // 返回值为对象类型的函数
        function func7() {
            return {
                name: 'shaosiming',
                age: 18
            }
        }

        // 返回值为函数类型的函数
        function func8() {
            return function(a, b) {
                return a * b
            }
        }
        console.log(func4()); // undefined
        console.log(func5()); // undefined
        console.log(func6(3, 5)); // 8
        console.log(func7()); // {name: 'shaosiming', age: 18}
        console.log(func8()); // 一个函数

全局作用域

在script标签中的代码都属于全局作用域代码

在全局作用域中有一个window对象, 代表的是当前页岩的浏览器窗口

在全局作用域中创建的变量会作为属性保存在window对象中

在全局作用域中创建的函数会任务方法保存在window对象中

在全局作用域中的变量和函数, 在任意位置都可以访问, 如: 在函数的作用域中可以访问全局作用域中的变量

        // 直接访问window对象
        console.log(window);

        // 全局作用域中的变量
        var a = 3

        // 在函数作用域中访问全局变量
        // 在函数中访问window对象
        function func() {
            console.log('func: ' + a);
            console.log("func: " + window);
        }
        func()

        // 我们还可以这样访问全局作用域中的变量和函数
        console.log(window.a);
        window.func()

函数作用域

函数的作用域, 每次执行创建, 执行完毕销毁, 因此每次调用函数都会创建一个新的作用域

在全局中创建的变量可以在函数中访问, 而在函数中创建的变量,不能在全局中访问

在函数中访问变量时的查找规则, 先在函数作用域中查找变量, 如果没有找到则往上寻找, 直到寻找到全局作用域, 如果在全局作用域中没有找到则是undefined

        let b = 3
        let c = 5
        function func2() {
            let b = 5
            console.log('func2: ' + b); // 在函数作用域中就可以查找到变量b, 因此输出5
            console.log('func2: ' + c); // 在函数作用域中找不到, 往上查找, 在全局作用域中找到c, 因此输出4
        }
        func2()
        console.log('global: ' + b); // 3

变量的提前声明

在全局作用域中和函数作用域中, var声明的变量会在所有代码执行前被声明, 但不会被赋值

因此我们可以在变量定义前使用变量

        console.log('global b: ' + b); // undefined
        var b = 3;

        function func3() {
            // console.log('func3: ' + a); // undefined
            // var a = 3; // 可以这样使用
            a = 3; // error: a is not defined
        }
        func3()

函数的提前声明

在全局作用域和函数作用域中, 使用function 函数名() {} 创建的函数, 会在所有代码执行前被创建, 因此我们可以在函数定义前调用函数, 但是var 函数名 = function() {}则不行

        func4(); // func4
        func5(); // eroro funct is not a function
        function func4() {
            console.log('func4');
        }

        var func5 = function() {
            console.log('func4');
        }

函数对象的call和apply方法

在进行函数调用的时候我们不但可以使用 函数名(); 这种方式调用

还可以使用 函数名.call(); 和 函数名.apply()进行调用

使用这两个方法来调用函数的时候, 可以指定函数中的this对象

在使用call方法是, 可以直接传实参. 而在使用apply方法, 需要将实参放入数组中, 再进行传递

        function func() {
            console.log('func:' + this);
        }

        func(); // this: 在这个函数中this是window对象

        func.call(); // this: window对象

        let person = {name: 'shaosiming', age: 18};
        func.call(person); // this指向person

        func.apply(person); // this指向person

函数对象的arguments属性

该属性存放着在调用函数时传递过来的实参

可以使用下标来获取参数

arguments.callee用来表示当前执行的函数对象

        function func() {
            console.log('func:' + this);
            console.log('args: ' + arguments[0] + ', ' + arguments[1] + ', ' + arguments[2]);
            console.log(arguments.callee); // 就是当前函数func
        }

        func.call(person, 1, 2);
        func.apply(person, [1, 2]);