1. 程式人生 > >JS高級. 04 增刪改查面向對象版歌曲管理、遞歸、

JS高級. 04 增刪改查面向對象版歌曲管理、遞歸、

for this調用 obj push 方法 solid 工具 條件 name

增 數組.push()

刪 數組.splice(開始刪除索引,刪除幾個)

在當前對象中調用當前對象的方法中和屬性,必須用this調用

nodeType判斷節點類型

節點.nodeType == 1:元素節點/2:屬性節點/3:文本節點

concat 返回的是一個新的數組

封裝歌曲列表管理(函數)

技術分享
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <script>
 7
var songList = [ 8 { 9 songName:"情書", 10 singer:"張學友" 11 }, 12 { 13 songName:"演員", 14 singer:"薛小謙" 15 }, 16 { 17 songName:"李白", 18 singer:"李榮浩" 19
} 20 21 ]; 22 //增刪該查 23 24 // 25 // function addSong(song){ 26 // songList.push(song); 27 // } 28 // 29 // addSong({ 30 // songName:"take me to your heart", 31 // singer:"邁克學搖滾" 32 // }); 33 // 34 // console.log(songList);
35 36 // 37 function removeSong(songName){ 38 var song = selectSong(songName); 39 var index = songList.indexOf(song); 40 songList.splice(index, 1); 41 // for (var i = 0; i < songList.length; i++) { 42 // var song = songList[i]; 43 // if(song.songName == songName){ 44 // //splice(起始索引,刪幾個) 45 // songList.splice(i, 1); 46 // } 47 // } 48 } 49 50 removeSong("李白"); 51 // 52 // console.log(songList); 53 // 54 // 55 function updateSong(songName, singer) { 56 57 var song = selectSong(songName); 58 song.singer = singer; 59 //遍歷歌曲列表,找到要修改的對象 60 // for (var j = 0; j < songList.length; j++) { 61 // var song = songList[j]; 62 // //判斷每次遍歷的對象的歌名,和要找的歌名是不是一一致,如果一致,就是我們要找的對象 63 // if(song.songName == songName){ 64 // //對找到的對象進行修改 65 // song.singer = singer; 66 // } 67 // } 68 } 69 // 70 // updateSong("演員","薛之謙"); 71 // console.log(songList); 72 // 73 // 74 function selectSong(songName) { 75 for (var k = 0; k < songList.length; k++) { 76 var song = songList[k]; 77 if(song.songName == songName){ 78 return song; 79 } 80 } 81 return null; 82 } 83 84 var obj = selectSong("情書1"); 85 console.log(obj); 86 // 87 // console.log(songList); 88 </script> 89 </head> 90 <body> 91 92 </body> 93 </html>
封裝歌曲列表管理(函數)

面向對象封裝歌曲管理

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script>

            function SongManager(){
                this.songList = null;
            }

            //在當前對象的方法中,調用當前對象的其他方法,需要使用this
            //例如 在 removeSong方法中調用 selectSong  this.selectSong
            SongManager.prototype = {
                init:function (songList) {
                    this.songList = songList;
                },

                addSong: function (song){
                    this.songList.push(song);
                },

                removeSong:function (songName){
                    var song = this.selectSong(songName);
                    if(song == null){
                        throw "您要刪除的歌曲不存在!請重新嘗試";
                    }
                    var index = this.songList.indexOf(song);
                    this.songList.splice(index, 1);
                },

                updateSong: function (songName, singer) {
                    var song = this.selectSong(songName);
                    if(song == null){
                        throw "您要修改的歌曲不存在!請重新嘗試";
                    }
                    song.singer = singer;
                },

                selectSong: function (songName) {
                    for (var k = 0; k < this.songList.length; k++) {
                        var song = this.songList[k];
                        if(song.songName == songName){
                            return song;
                        }
                    }
                    return null;
                }
            };

            var pwbDEManager = new SongManager();
            pwbDEManager.init([
                {
                    songName:"青藏高原",
                    singer:"潘文斌"
                },
                {
                    songName:"我的換板鞋,摩擦摩擦最時尚",
                    singer:"約翰遜,龐麥郎"
                }
            ]);
            pwbDEManager.addSong({
                songName:"東風破",
                singer:"Jay Chou"
            })

            var gjbDEManager = new SongManager();
            gjbDEManager.init([
                {
                    songName:"兩只老虎",
                    singer:"高金彪"
                },
                {
                    songName:"粉刷匠",
                    singer:"高金彪"
                }
            ]);
    //        gjbDEManager.removeSong("李白");
            gjbDEManager.removeSong("兩只老虎");
            console.log(pwbDEManager.songList);
            console.log(gjbDEManager.songList);


            //要封裝一個歌曲管理的工具
            //特征:歌曲列表
            //行為:增  刪  改 查
        </script>
    </head>
    <body>

    </body>
    </html>

遞歸(練習在最底下)

1.在函數內調用函數自己,就是遞歸
2.函數不調用不占用內存
3.沒有遞歸結束條件的遞歸就是死隊規

遞歸的兩個要素

1.自己調用自己
2.要有結束的條件

化歸思想:把問題由難化易,化繁為簡,有復雜變簡單的過程成為化歸

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        window.onload = function () {
            //給頁面中所有的元素添加一個邊框  1px solid pink
            //DOM中,沒有提供直接獲取後代元素的API
            //但是可以通過childNodes來獲取所有的子節點

            //先找body的所有子元素
            //再找body的子元素的所有子元素

            function getChildNode(node){
                //先找子元素
                var nodeList = node.childNodes;
                //在用子元素再找子元素  這裏就可以遞歸了
                //for循環中的條件,就充當了結束的條件
                for (var i = 0; i < nodeList.length; i++) {
                    //childNode獲取到到的節點包含了各種類型的節點
                    //但是我們只需要元素節點  通過nodeType去判斷當前的這個節點是不是元素節點
                    var childNode = nodeList[i];
                    //判斷是否是元素節點
                    if(childNode.nodeType == 1){
                        childNode.style.border = "1px solid pink";
                        getChildNode(childNode);
                    }
                }
            }
            getChildNode(document.body);
        }
    </script>
</head>
<body>
<div>1div
    <p>1p<span>1span</span><span>2span</span><span>3span</span></p>
    <p>5p<span>1span</span><span>2span</span><span>3span</span></p>
</div>
<div>10div
    <p>1p<span>1span</span><span>2span</span><span>3span</span></p>
    <p>5p<span>1span</span><span>2span</span><span>3span</span></p>
</div>
<p>我是第1個p標簽</p>
<p>我是第10個p標簽</p>
</body>
</html>

方式二

    <script>


        window.onload = function () {
            //給頁面中所有的元素添加一個邊框  1px solid pink
            //DOM中,沒有提供直接獲取後代元素的API
            //但是可以通過childNodes來獲取所有的子節點

            //先找body的所有子元素
            //再找body的子元素的所有子元素
            function getChildNode(node){
                //先找子元素
                var nodeList = node.childNodes;
                var result = [];
                //在用子元素再找子元素  這裏就可以遞歸了
                //for循環中的條件,就充當了結束的條件
                for (var i = 0; i < nodeList.length; i++) {
                    //childNode獲取到到的節點包含了各種類型的節點
                    //但是我們只需要元素節點  通過nodeType去判斷當前的這個節點是不是元素節點
                    var childNode = nodeList[i];
                    //判斷是否是元素節點
                    if(childNode.nodeType == 1){
                        result.push(childNode);
                        var temp = getChildNode(childNode);
                        result = result.concat(temp);
                    }
                }
                return result;
            }

            //1.第一次調用時獲取body的所有子元素,會把所有的子元素全部放到result裏面
            //2.每放進去一個 就找這個子元素的所有子元素  有返回值
            //3.把這個返回值和我們存當前子元素的數組拼接起來 就變成了 子元素 和 孫子元素的集合
            var arr = getChildNode(document.body);

            for (var i = 0; i < arr.length; i++) {
                var child = arr[i];
                child.style.border= "1px solid pink";
            }
        }
    </script>

遞歸

例子:

1, 2, 3, 4, 5, ..., 100 求和

  1. 首先假定遞歸函數已經寫好, 假設是foo. 即foo(100)就是求1100的和

  2. 尋找遞推關系. 就是nn-1, 或n-2之間的關系:foo( n ) == n + foo( n - 1 )

var res = foo(100);
var res = foo(99) + 100;

將遞推結構轉換為遞歸體

function foo(n){
    return n + foo( n - 1 );
}

上面就是利用了化歸思想:

  • 將 求 100 轉換為 求 99

  • 將 求 99 轉換為 求 98

  • ...

  • 將求 2 轉換為 求 1

  • 求 1 結果就是 1

  • 即: foo( 1 ) 是 1

將臨界條件加到遞歸體中(求1的結果為1)

function foo( n ) {
    if ( n == 1 ) return 1;
    return n + foo( n - 1 );
}

練習:

求 1, 3, 5, 7, 9, ... 第n項的結果與前n項和. 序號從0開始

先看求第n
  1. 首先假定遞歸函數已經寫好, 假設是fn. 那麽第n項就是fn(n)

  2. 找遞推關系:fn(n) == f(n-1) + 2

  3. 遞歸體

function fn(n) {
    return fn(n-1) + 2;
}
  1. 找臨界條件

    • 求 n -> n-1

    • 求 n-1 -> n-2

    • ...

    • 求 1 -> 0

    • 求 第 0 項, 就是 1

  2. 加入臨界條件

function fn( n ) {
    if ( n == 0 ) return 1;
    return fn( n-1 ) + 2;
}
再看求前n項和
  1. 假設已完成, sum( n ) 就是前 n 項和

  2. 找遞推關系: 前 n 項和 等於 第 n 項 + 前 n-1 項的和

  3. 遞歸體

function sum( n ) {
    return fn( n ) + sum( n - 1 );
}
  1. 找臨界條件

    • n == 1結果為 1
  2. 加入臨界條件

function sum( n ) {
    if (n == 0) return 1;
    return fn(n) + sum(n - 1);
}

練習

2, 4, 6, 8, 10 第 n 項與 前 n 項和

解題方法和上一題一樣。

練習

現有數列: 1, 1, 2, 4, 7, 11, 16, … 求 第 n 項, 求前 n 項和.

求第n
  1. 假設已經得到結果 fn, fn( 10 ) 就是第 10 項

  2. 找遞推關系

    • 0, 1 => fn( 0 ) + 0 = fn( 1 )

    • 1, 2 => fn( 1 ) + 1 = fn( 2 )

    • 2, 3 => fn( 2 ) + 2 = fn( 3 )

    • ...

    • n-1, n => fn( n-1 ) + n - 1 = fn( n )

  3. 遞歸體也就清楚了

  4. 臨界條件是 n == 0 => 1

function fn( n ) {
    if ( n == 0 ) return 1;
    return fn( n-1 ) + n - 1;
}
n項和
function sum( n ) {
    if ( n == 0 ) return 1;
    return sum( n - 1 ) + fn( n );
}

練習

Fibonacci 數列: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, … 求其第 n 項.

遞推關系:fn(n) == fn(n-1) + fn(n - 2)

function fib( n ) {
    if ( n == 0 || n == 1 ) return 1;
    return fib( n - 1 ) + fib( n - 2 );
}

練習

階乘:一個數字的階乘表示的是從 1 開始 累乘到這個數字. 例如 3! 表示 1 2 3. 5! 就是 1 2 3 4 5. 規定 0 沒有階乘, 階乘從1開始。

求n的階乘

function foo ( n ) {
    if ( n == 1 ) return 1;
    return foo( n - 1 ) * n;
}

練習

求冪

  • 求冪就是求 某一個數 幾次方

  • 2*2 2 的 平方, 2 的 2 次方

  • 求 n 的 m 次方

  • 最終要得到一個函數 power( n, m )

  • n 的 m 次方就是 m 個 n 相乘 即 n 乘以 (m-1) 個 n 相乘

function power ( n, m ) {
    if ( m == 1 ) return n;
    return power( n, m - 1 ) * n;
}

JS高級. 04 增刪改查面向對象版歌曲管理、遞歸、