js函数进阶

Posted cuter、

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js函数进阶相关的知识,希望对你有一定的参考价值。

一、函数的定义和调用

1.1函数的定义方式

在这里插入图片描述
在这里插入图片描述

  //1.自定义函数
        function fn(a, b) {
            return a + b;

        };
        fn(1, 2);
        //2.函数表达式定义
        var fn = function() {

        };
        //3.利用 new Function (‘参数1’,‘参数2’,‘参数3’)
        var f = new Function('a', 'b', 'console.log(a+b)');
        f(1, 2);
        //4.所有函数都是 Function的实例(对象)
        //5.函数也属于对象
        console.log(f instanceof Object);

1.2函数的定义方式

在这里插入图片描述
1.普通函数

function fn() {

        }
        fn();
        fn.call();

2.对象的方法

 var obj = {
            sayhi: function() {

            }
        }
        obj.sayhi();

3.构造函数

 function Fn() {

        }
        new Fn()

4.绑定事件函数

 btn.onclick = function() {

        }

5.定时器函数

 setInterval(function() {

        })

6.立即执行函数

 
            (function() {

            })()
            
            (function() {

            }())

二、this

2.1this的指向问题

在这里插入图片描述

2.1.1call方法

在这里插入图片描述

//1.call
        var o = {
            name: 'andy'
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        fn.call(o, 1, 2);
        //call第一个可以调用函数  第二个可以改变函数内的this指向
        //call的主要左右可以实现继承
        function Father(uname, age, sex) {
            this.uname = uname;
            this.age = age;
            this.sex = sex;
        }

        function Son(uname, age, sex) {
            Father.call(this, uname, age, sex);
            //this 继承父类的属性
        }
        var son = new Son('刘德华', 18, '男');
        console.log(son);

2.1.2apply方法

在这里插入图片描述

  //1.apply
        var o = {
            name: 'andy'
        };

        function fn(arr) {
            console.log(this);
            console.log(arr); //xu

        };
        fn.apply(o, ['xu']);
        //1.也是调用函数  可以改变函数内部的this指向 
        //2.但是他的参数  必须是数组(伪数组)
        //3.apply的主要应用  比如说我们可以利用apply借助于数学内置对象求最大值
        //Math.max()
        var arr = [1, 6, 99, 3, 45];
        var max = Math.max.apply(Math, arr); //因为是Math调用了max 所以要指向Math
        var min = Math.min.apply(Math, arr); //因为是Math调用了max 所以要指向Math
        console.log(max); //99
        console.log(min); //1

2.1.3bind方法

在这里插入图片描述

 <button>点击</button>
    <script>
        // var o = {
        //     name: 'xu'
        // };

        // function fn(a, b) {
        //     console.log(this);
        //     console.log(a + b); //3

        // };
        // var f = fn.bind(o, 1, 2);
        // f();
        //1.不会调用原来的函数  可以改变原来函数内部的this指向  
        //2.返回的是原函数改变this之后产生的新函数
        //3.如果有的函数不需要立即调用 但是又想改变函数内部的this指向  此时用bind方法
        //我们有一个按钮  点击后就禁用这个按钮  3秒之后就可以解除禁用
        var btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            this.disabled = true; //这个this指向的是btn这个按钮
            //var that = this;
            setTimeout(function() {
                //定时器里面的函数指向的是window对象
                //that.disabled=false;
                this.disabled = false;
            }.bind(this), 3000); //这个this指向的是btn这个对象

        });

在这里插入图片描述

2.2bind 、call、apply方法总结

在这里插入图片描述

三、严格模式

3.1什么是严格模式

在这里插入图片描述

3.2开启严格模式

在这里插入图片描述
在这里插入图片描述

  <!-- 为整个脚本script标签开启严格模式 -->
    <script>
        'use strict'
        //下面的js代码就会按照严格模式执行代码
    </script>
    <script>
        (function() {
            'use strict';
        })();
    </script>

2.为函数开启严格模式

 <script>
        //为函数开启严格模式
        function fn() {
            //此时只是给fn 开启了严格模式  下面的代码按照严格模式执行
            'use strict';

        }

        function fun() {
            //还是按照普通模式执行

        }
    </script>

3.3严格模式中的变化

在这里插入图片描述
在这里插入图片描述

<script>
        'use strict';
        var num = 10;
        console.log(num);
        //我们不能随意删除已经声明好的变量
        delete num;
        //在严格模式下 全局作用域中 函数的this指向的是 undefined
        function fn() {
            console.log(this); //undefined  
        };
        fn();
        // 严格模式下 构造函数不加new调用 ,this会报错
        function Star() {
            this.sex = '男';
        };
        // Star();
        // console.log(window.sex);
        var ldh = new Star();
        console.log(ldh.sex); //男
    </script>

四、高阶函数

在这里插入图片描述
在这里插入图片描述

五、闭包

5.1变量作用域

在这里插入图片描述

5.2什么是闭包

在这里插入图片描述

  //闭包:我们fun这个函数作用域 访问了另外一个函数fn里面的局部变量 num
        //fn是闭包
        function fn() {
            var num = 10;

            function fun() {
                console.log(num); //10
            }
            fun();
        }
        fn();

在这里插入图片描述

5.3闭包的作用

延伸了作用范围

<script>
        //闭包:我们fun这个函数作用域 访问了另外一个函数fn里面的局部变量 num
        //fn是闭包
        //我们fn外面的作用域可以访问fn内部的局部变量
        function fn() {
            var num = 10;

            function fun() {
                console.log(num); //10
            }
            return fun();
        }
        var f = fn();
        f();
        //类似于
        var f = function fun() {
            console.log(num); //10
        };
    </script>

5.3.1闭包案例 点击li获得索引号

 //闭包应用 点击li输出当前li的索引号
        //1.我们可以利用动态添加属性的方法
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = function() {
                console.log(i);
                lis[i].index = i;

            }
        }
        //2.利用闭包的方式得到当前li的索引号
        for (var i = 0; i < lis.length; i++) {
            //利用for循环创建了四个立即执行函数
            //立即执行函数也称为小闭包  因为立即执行函数里面的任何一个函数都可以使用它的i这变量
            (function(i) {
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);
                }

            })(i);
        }

5.3.2闭包案例 定时器闭包

  <ul class="nav">
        <li>榴莲</li>
        <li>饺子</li>
        <li>你好</li>
        <li>苹果</li>
        <li>香蕉</li>
    </ul>
    <script>
        //闭包应用 3秒钟之后,打印所有的li元素
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerhtml);
                }, 3000)
            })(i)
        }
    </script>

在这里插入图片描述

5.3.3闭包案例 计算打车价格

<script>
        //闭包应用-计算打车价格
        //打车起步13(3公里内)  之后每一公里加五块钱  用户输入公里数可以计算打车价格
        //如果有拥堵情况,总价多收取10块钱拥堵费
        //function fn() {};
        //fn();
        var car = (function() {
            var start = 13; //起步价
            var total = 0; //总价
            return {
                price: function(n) { //正常总价
                    if (n <= 3) {
                        total = start;
                    } else {
                        total = start + (n - 3) * 5
                    }
                    return total;
                },
                yd: function(flag) { //拥堵之后的费用
                    return flag ? total + 10 : total;
                }
            }

        })();
        console.log(car.price(5)); //23
        console.log(car.yd(true)); //33

        console.log(car.price(1)); //13
        console.log(car.yd(false)); //13
    </script>

在这里插入图片描述

六、递归

6.1递归

在这里插入图片描述

 //递归函数:函数内部自己调用  ,这个函数就是递归函数
        var num = 1;
        function fn() {
            console.log('我要打印6句话');
            if (num == 6) {
                return; //递归里面必须加退出条件
            }
            num++;
            fn();
        }
        fn();

6.1.1利用递归求 1到n的阶乘

script>
        //利用递归函数求1~n的阶乘 1* 2 *3*...n

        function fn(n) {
            if (n === 1) {
                return 1;
            }
            return n * fn(n - 1);
        }
        console.log(fn(3));//6
        //详细思路  假如用户输入3
        // return 3 * fn(2)
        // return 3 * (2*fn(2-1))
        // return 3 * (2*fn(1))
        // return 3 * (2*1)
        // return 6

6.1.2利用递归求 斐波那契数列

 //利用递归函数求斐波那契数列(兔子序列) 1、1、2、3、5、8、13、21...
        //用户输入一个数字n就可以求出这个数字对应的斐波那契数列值
        //我们只需要知道用户输入的n的前面两项(n-1 n-2)  就可以计算出n的序列值
        function fb(n) {
            if (n === 1 || n === 2) {
                return 1;
            }
            return fb(n - 1) + fb(n - 2);
        }
        console.log(fb(5));//5

6.1.3利用递归求 id商品号

 <script>
        var data = [{
            id: 1,
            name: '家电',
            goods: [{
                id: 11,
                gname: "冰箱"
            }, {
                id: 12,
                gname: "洗衣机"

            }]
        }, {
            id: 2,
            name: "服饰"
        }];
        //1.利用foreach遍历里面每一个对象
        function getId(json, id) {
            var o = {}
            json.forEach(function(item) {
                if (item.id === id) {
                    // console.log(item);
                    o = item;
                    return item;
                    //我们想要得到里层的数据,可以利用递归函数
                    //里面应该有goods这个数组  并且数组的长度不为0
                } else if (item.goods && item.goods.length > 0) {
                    o = getId(item.goods, id);
                }
            });
            return o;

        }
        console.log(getId(data, 1));
        console.log(getId(datajs代码片段: utils/lcoalStorage/cookie

javascript进阶笔记

几个关于js数组方法reduce的经典片段

web代码片段

JavaScript进阶之执行上下文和执行栈

Atom编辑器入门到精通 Atom使用进阶