1. 程式人生 > 其它 >JavaScript03:函式和方法

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>