JavaScript03:函数和方法

函数和方法是一样的,只是对于对象来说,函数被绑定在对象上,称为这个对象的方法

JavaScript的函数也被看作是对象,可以被赋值,可以传任意个参数不报错,参数少了返回undefined或NaN,参数多了忽略

函数定义和参数

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">
    <title>我的网页</title>

    <script>

        "use strict";

        /**
         * 函数定义方式一:function 函数名(){}
         */
        function abs1(x){

            if (x < 0){
                return -x;
            }

            return x;
        }

        /**
         * 函数定义方式二:let 函数名 = function(){}
         * 函数也是对象,可以赋值给变量
         */
        let abs2 = function (x){

            if (x < 0){
                return -x;
            }

            return x;
        }
        
        /**
         * alert()方法可以被赋值失效
         */
        alert = function(){};
        alert("Hello");

        /**
         * 如果调用时没有参数,手动抛出异常
         */
        function test1(x){

            if (typeof x !== "number"){
                throw "Not a number"
            }
        }

        /**
         * 如果调用时传入参数多了,后面的会忽略,但是可以用arguments关键字数组获取到
         * arguments数组记录了所有传进的参数,包括未定义的多余参数,且只能用for循环遍历出未定义的参数
         */
        function test2(x){

            if (arguments.length > 1){

                for (let i = 0; i < arguments.length; i++) {
                    console.log(arguments[i]);
                }
            }
            else {
                return x;
            }
        }

        /**
         * rest可变长参数数组,可以单独获得未定义的传参值
         */
        function test3(x, ...rest){

            console.log(x);
            console.log(rest);
        }

    </script>

</head>

<body>

</body>

</html>

变量作用域

变量如果不用var或者let定义,会自动被声明为全局变量,很不安全,因此要使用strict模式,强制用let或var定义

var是函数作用域,变量只在函数内是有效的,先使用后声明也行,但值是undefined,可以被重新定义。在for循环定义一个var变量,在for循环外也可以访问

let是块作用域,变量只在块中有效,必须先声明再使用。在for循环定义一个let变量,在for循环外是不可被访问的,所以for循环推荐用let

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">
    <title>我的网页</title>

    <script>

        "use strict";

        function test1(){

            var x = "x" + y;
            console.log(x);
            var y = "y";
        }

        function test2(){

            let x = "x" + y;
            console.log(x);
            let y = "y";
        }

        /**
         * var定义变量,如果先使用后定义,会自动提升变量作用域(值为undefined),不会报错
         * 而let未定义使用会报错
         * 因此建议所有变量定义都放在头部
         */
        test1();
        test2();

    </script>

</head>

<body>

</body>

</html>

全局变量和常量

不在任何函数内定义的变量就是全局变量,而所有全局变量都被绑定为全局对象window的属性,如alert()方法,定义的全局变量等

可以通过默认的window对象调用所有全局变量,每个文件可以自定义一个全局对象,间接创建调用其他变量,避免和其他文件冲突

const关键字定义常量,全部大写

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">
    <title>我的网页</title>

    <script>

        "use strict";

        /**
         * 任何全局变量都是window对象的属性,可以直接调用
         */
        window.alert("Hello");

        /**
         * 自定义一个全局对象,又称命名空间,间接创建调用其他变量
         */
        let MyName = {};

        MyName.name = "ty";
        console.log(MyName.name);

        /**
         * const关键字定义常量
         */
        const PI = "3.14";
        console.log(PI);

    </script>

</head>

<body>

</body>

</html>

方法

方法就是把函数放在对象的内部,对象只有属性和方法

apply()/call()方法可以让this指定对象,方便多个对象调用同一个方法,不同点是apply()方法传入参数列表,call()一个个传入参数

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">
    <title>我的网页</title>

    <script>

        "use strict";

        let xiaoming = {

            /**
             * 属性
             */
            name: "xiaoming",
            birth: 1990,

            /**
             * 方法
             * 定义方式一
             */
            age: function (){

                let now = new Date().getFullYear();
                return now - this.birth;
            },

            /**
             * 定义方式二
             * 将方法具体内容写在外面,只引用方法名
             */
            address: name
        }

        function name (){
            return this.name;
        }

        let xiaohong = {

            name: "xiaohong",
            address: name
        }

        console.log(xiaoming.age());
        console.log(xiaoming.address());

        /**
         * 方式二中不能直接调用这个name()方法,因为默认是用window对象来调用,而window没有name这个属性
         * 可以通过apply()/call()方法来指定this指向的对象(分别传入要指向的对象,还有参数),方便多个对象调用同一个方法
         */
        console.log(name);
        console.log(name.apply(xiaoming, []));
        console.log(name.call(xiaohong, ));

    </script>

</head>

<body>

</body>

</html>
posted @ 2022-03-23 09:07  振袖秋枫问红叶  阅读(47)  评论(0)    收藏  举报