JS高级. 04 增删改查面向对象版歌曲管理、递归、

增 数组.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 3. 5! 就是 1 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;
}

 

posted @ 2017-10-21 23:53  明明明明明明明明  阅读(529)  评论(0编辑  收藏  举报