天天看點

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

目錄

【第二章】函數進階

| (複習)函數聲明

| 函數也是對象

| 函數的this指向

| 改變函數this的指向

| 函數的“嚴格模式”

| 閉包

| 淺拷貝和深拷貝

【第二章】函數進階

| (複習)函數聲明

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

| 函數也是對象

Java中的方法好像不是對象!隻是對象的一個方法

函數是對象,函數也有Function的原型對象。所有的函數的f對象執行個體也可以通路其prototype原型對象。

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

| 函數的this指向

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

| 改變函數this的指向

方法1:call()

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

方法2:apply()

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

方法3:bind()

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

三者總結

【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

| 函數的“嚴格模式”

更多嚴格模式要求參考:嚴格模式 - JavaScript | MDN

| 閉包

什麼是閉包

  • 閉包就是一個函數:變量所在的函數就是閉包(函數)
  • 也可以說:任何一個函數的作用域,如果可以通路其它函數内部的局部變量,則産生了閉包現象
【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

 閉包的作用:在f 作用域的外部,通路f作用域内的局部變量

在JS中,方法(函數)是一個對象,是以可以return

代碼示例

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function fn(){
            var num = 10;

            function fun(){
                console.log(num);
            }


            return fun;
        }

        var newf = fn();//獲得傳回的fun函數,相當于把fun拿出來了,這樣就可以在 fn的作用域外,使用到了其作用域内的局部變量num啦
        newf(); //10  相當于把【 fn(); → fn調用了fun();】 直接整合為了  【newf();】


    </script>
</head>
<body>
    
</body>
</html>
           

| 淺拷貝和深拷貝

淺拷貝

  • 淺拷貝指的是:不同對象之間指派,若是基本資料類型,則可以完整獨立地指派給新對象,但是對于對象内的對象類型,則隻能指派位址給新對象
  • 淺拷貝示例
【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

淺拷貝文法(文法糖,即上述for循環周遊指派的JS的一個内置函數封裝)

Object.assign(Ctrl+V的對象, Ctrl+C的對象); 
           
【第六部分 | JavaScript進階】2:函數進階【第二章】函數進階

深拷貝

  • 原理:利用遞歸函數,把對象中的對象也用for循環指派給新的對象
  • 深拷貝沒有文法糖,需要我們自己編寫函數!
<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        //old obj
        var obj = {
            name: 'Klee',
            age: 10,
            features: {
                color: 'red',
                hobby: 'fishing'
            }
        }

        //new obj
        var newObj = {}

        //deepcopy
        function deepCopy(newObj , oldObj){
            for(var k in oldObj){
                //擷取屬性值
                var item = oldObj[k];

                //判斷是否是對象,若是,則遞歸調用deepcopy
                if(item instanceof Array){
                    //新對象的第k個屬性是數組  newObj[k]代表對象nowObj的第k個索引的對象(複習for(in)文法)
                    newObj[k] = []; 
                    deepCopy(newObj[k],item);//遞歸給數組指派
                }

                //判斷是否是數組,若是,則遞歸調用deepcopy
                else if(item instanceof Object){
                    newObj[k] = {};
                    deepCopy(newObj[k],item);
                }

                //其他情況,則說明該屬性是基本資料類型
                else{
                    newObj[k] = item;
                }
            }
        }

        //測試
        console.log('最開始的obj');
        console.log(obj.features.hobby);

        deepCopy(newObj , obj);
        
        console.log('調用了deepcopy後的obj、newObj');
        console.log(obj.features.hobby);
        console.log(newObj.features.hobby);

        newObj.features.hobby = 'eating';
        console.log('修改了newObj中對象的屬性後的obj、newObj');
        console.log(obj.features.hobby);
        console.log(newObj.features.hobby);
        


    </script>
</head>
<body>
    
</body>
</html>
           

繼續閱讀