zoukankan      html  css  js  c++  java
  • ES5-ES6-ES7_函数的扩展

    call()/apply()/bind()的用法

    Function.prototype.bind(obj) :将函数内的this绑定为obj, 并将函数返回

    function foo() {
      console.log(this) // this指向window
    }
    foo()
    let obj = {userName: 'huang'}
      function foo() {
        console.log(this) // this指向obj
        console.log(this.userName) // huang
      }
      foo.call(obj)
    let obj = {userName: 'huang'}
      function foo() {
        console.log(this) // this指向obj
        console.log(this.userName) // huang
      }
      foo.apply(obj)
      let obj = {userName: 'huang'}
      function foo( ) {
        console.log(this) // this指向obj
        console.log(this.userName) // huang
        console.log(data)
      }
      foo.apply(obj, [33]) //apply传参数要用数组,第二个参数必须是数组
      foo.call(obj, 33) // 直接从第二个参数开始依次传入
    let obj = {userName: 'huang'}
      function foo() {
        console.log(this) // this指向obj
        console.log(this.userName) // huang
      }
      var bar = foo.bind(obj) //绑定完this不会立刻调用当前的函数,而是将函数返回
      bar()
    let obj = {userName: 'huang'}
      function foo(data) {
        console.log(this) // this指向obj
        console.log(this.userName) // huang
        console.log(data)
      }
      var bar = foo.bind(obj, 33) //绑定完this不会立刻调用当前的函数,而是将函数返回
      bar()

    区别bind()与call()和apply(): 都能指定函数中的this,call()/apply()是立即调用函数,bind()是将函数返回

    bind()一般在回调函数中使用,在回调函数中将this指向某个对象,然后进行操作(拿对象的属性进行对比,赋值等操作)

    箭头函数的用法

    箭头函数的作用是定义匿名函数,使用场景: 多用来定义回调函数

    ES6 允许使用“箭头”(=>)定义函数,如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

    当箭头函数没有参数的时候的写法

    //箭头函数不需要参数
    var f = () => 5;
    
    // var f = function () {
    //     return 5
    // };
    
    console.log(f())  //5

     当箭头函数只有一个参数的时候的写法

    //当函数只需要一个参数的时候的写法
    var f = v => v;
    
    // var f = function(v) {
    //     return v;
    // };
    
    console.log(f('333'))  //333

     当箭头函数有多个参数的时候的写法

    //当箭头函数需要多个参数
    var sum = (num1, num2) => num1 + num2;
    
    // var sum = function(num1, num2) {
    //     return num1 + num2;
    // };
    
    console.log(sum(3,8))  //11

    函数体如果有多个语句, 需要用{}包围,若有需要返回的内容,需要手动返回

    //如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回,每个函数都会有返回值,如果没有写默认就是undefined
    var sum = (num1, num2) => {
        num1 = num1*2;
        num2 = num2*3;
        return num1 + num2;
    }
    console.log(sum(1,2))  //8
    //由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
    var getTempItem = (id,name)=> ({ id: id, name: name });
    console.log(getTempItem(3,'huangjianfng'));//{ id: 3, name: 'huangjianfng' }

    箭头函数的特点
    简洁,箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this
    一个正常的函数是谁调用他,this代表的是谁,而箭头函数正好相反。this对象的指向是可变的,但是在箭头函数中,它是固定的。

    不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

    不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

    <body>
        <button id="btn1">测试箭头函数this_1</button>
        <button id="btn2">测试箭头函数this_2</button>
    <script type="text/javascript">
        let btn1 = document.getElementById('btn1')
        let btn2 = document.getElementById('btn2')
    
        btn1.onclick = function () {
            alert(this.innerHTML) //this就是btn1
        }
        btn2.onclick = () => {
            alert(this) // this是window,因为btn2是定义在全局下的
        }
    </script>
    </body>

    扩展理解: 箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。

    <body>
        <button id="btn1">测试箭头函数this_1</button>
        <button id="btn2">测试箭头函数this_2</button>
    <script type="text/javascript">
        let btn1 = document.getElementById('btn1')
        let btn2 = document.getElementById('btn2')
    
        btn1.onclick = function () {
            alert(this.innerHTML) //this就是btn1
        }
    
    
        let obj = {
            name: '箭头函数',
            getName(){
                btn2.onclick = () => {
                    console.log(this) // this是obj
                }
            }
        }
        obj.getName()
    </script>
    </body>
    <body>
        <button id="btn1">测试箭头函数this_1</button>
        <button id="btn2">测试箭头函数this_2</button>
    <script type="text/javascript">
        let btn1 = document.getElementById('btn1')
        let btn2 = document.getElementById('btn2')
    
        btn1.onclick = function () {
            alert(this.innerHTML) //this就是btn1
        }
    
    
        let obj = {
            name: '箭头函数',
            getName: () => {
                btn2.onclick = () => {
                    console.log(this) // this是window
                }
            }
        }
        obj.getName()
    </script>
    var id = 21;
        function foo() {
            setTimeout(() => {
                console.log(this);// 这时候this是window,因为foo方法在全局调用,foo方法的this是window
            }, 100);
        }
    
        foo(); //
    function foo() {
        setTimeout(() => {
            console.log(this.id);  //42,因为foo的this绑定到了id为42的这个对象中,所以this就是这个对象
        }, 100);
    }
    
    var id = 21;
    
    foo.call({ id: 42 });

    rest 参数与箭头函数结合

    const numbers = (...nums) => {
        var i = 0;
        for(var val of nums){
            i += val;
        }
        return i
    };
    
    console.log(numbers(1, 2, 3, 4, 5))  //15
    const numbers = (a,...nums) => {
        var i = a;
        for(var val of nums){
            i += val;
        }
        return i
    };
    
    console.log(numbers(100,1, 2, 3, 4, 5))  //115

    使用箭头函数数组排序

    var arr = [2,6,1,7,3];
    
    // arr.sort(function (a,b) {
    //     return a-b;
    // })
    // console.log(arr)
    
    arr.sort(( a, b ) => a - b );
    console.log(arr)   //[ 1, 2, 3, 6, 7 ]

    rest 参数

    在rest参数之前,有个arguments对象,可以获取到函数的参数

    function sum() {
        var args = arguments; //arguments是个伪数组,不能使用一般数组的方法
        var res = 0;
        for (var i = 0;i < args.length;i++){
            res += args[i];
        }
        return res;
    }
    console.log(sum(1,2,3,4,5));  //15

     ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

    function add(...values) {   // add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数
        let sum = 0;
        for (var val of values) {
            sum += val;
        }
        return sum;
    }
    console.log(add(2, 5, 3));   // 10

    函数的参数可以很多个,但是rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错,在rest参数之前可以有很多个

    function add(a,...values) {   // add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数
        let sum = a;
        for (var val of values) {
            sum += val;
        }
        return sum;
    }
    console.log(add(10,2, 5, 3));   // 20,第一个参数10代表的是参数a,后面三个参数代表的是rest参数(...values)

    扩展运算符

    let arr1 = [1,3,5];
    let arr2 = [2,...arr1,6]; // 将arr1插入到arr2的数组中间
    console.log(...arr2) // 自动遍历

    为函数参数指定默认值

    function log(x, y) {
        y = y || 'World';
        console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    //这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,则该赋值不起作用,参数y等于空字符,结果被改为默认值
    log('Hello', '') // Hello World

    ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面,使用这种写法更好

    function log(x, y = 'World') {
        console.log(x, y);
    }
    console.log('Hello') // Hello World
    console.log('Hello', 'China') // Hello China
    console.log('Hello', '') // Hello

    参数变量是默认声明的,所以不能用let或const再次声明

    function foo(x = 5) {
    
        //参数变量x是默认声明的,在函数体中,不能用let或const再次声明,否则会报错
        let x = 1; // error
        const x = 2; // error
    }

    使用参数默认值时,函数不能有同名参数

    // SyntaxError: Duplicate parameter name not allowed in this context
    function foo(x, x, y = 1) {
        console.log(x,y)
    }

     参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的

    let x = 99;
    function foo(p = x + 1) {
        console.log(p);
    }
    foo() // 100
    foo() // 100
    x = 100;
    foo() //101
  • 相关阅读:
    XML应用程开发--下
    XML应用程序开发--上
    TCP通信客户端简单示例
    TCP网络通信服务器端简单示例
    XML基本内容学习笔记
    如何在Qt的widget上右键显示菜单
    关于双指针遍历
    常见的四种排序算法
    JAVA Class13
    JAVA练习
  • 原文地址:https://www.cnblogs.com/LO-ME/p/10584940.html
Copyright © 2011-2022 走看看