zoukankan      html  css  js  c++  java
  • JavaScript 中 call,apply 和 bind

      call and apply
       改变函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。

    function test() {} 
    test() == test.call()
    
    var obj ={};
    Object.prototype.toString.call(obj) //"[object Object]"
    //因为call 和 apply 会将函数中的this指向第一个参数
    上面代码相当于 obj.toString() 

    1. call 和apply 区别在于传参:

    • call 第二个参数开始单个单个参数传
    • apply 第二个参数为数组或类数组
    var a = [1, 2, 4, 1, 15];
    Math.max.apply(null, a) // 15
    
    Math.max.call(null,  1, 2, 4, 16, 15) // 16
    
    //将数组的空元素变为undefined
    
    Array.apply(null [1,,3,,4) //[1,undefined,3,undefined,4];

      第一个参数为空、null和undefined,则默认传入全局对象。

    2. 空元素与undefined的区别

    • 数组的 forEach方法会跳过空元素,但是不会跳过undefined。因此,遍历内部元素的时候,会得到不同的结果。


    3. 转换类似数组的对象

    • 被处理的对象必须有length属性,以及相对应的数字键。
    let obj = { 0: 1, length: 2 };
    let obj1={ 0: 1,1: 2, length: 2 };
    
    Array.protetype.slice.apply(obj);//[1,undefined]
    
    Array.protetype.slice.apply(obj1);//[1,2]

     bind方法

    用于将函数体内的this绑定到某个对象,然后返回一个新函数。

    var counter = {
    count: 0,
    a: function () {
    this.count++;
       }
    };
    
    var func = counter.a.bind(counter);
        func();
      counter.count // 1
    
      var add = function (x, y) {
       return x * this.m + y * this.n;
      }
    
     var obj = {
         m: 2,
         n: 2
      };
    
    var newAdd = add.bind(obj, 5); //将x 绑定为 5 
    newAdd(5) // 20
    newAdd(1,5)//12

      第一个参数是null或undefined,等于将this绑定到全局对象  

    bind方法使用注意点

    • bind方法每运行一次,就返回一个新函数, 需要一个变量接收
    • 结合回调函数使用
    var counter = {
        count: 0,
        inc: function () {
            'use strict';
            this.count++;
        }
    };
    
    function callIt(callback) {
        callback();
    }
    
    callIt(counter.inc.bind(counter));
    counter.count // 1

     结合call方法使用

    1. 正常使用slice

     [1, 2, 3].slice(0, 2) // [1,2]
    // 等同于
    Array.prototype.slice.call([1, 2, 3], 0, 2) // [1,2]

     2. 将Array.prototype.slice变成Function.prototype.call方法所在的对象,调用时就变成了Array.prototype.slice.call。

    var slice = Function.prototype.call.bind(Array.prototype.slice);
    Function.prototype.slice.call([1, 2, 3], 0, 1) // [1]
    //slice([1, 2, 3], 0, 1) 

    3. 类似的写法还可以用于其他数组方法。

    var push = Function.prototype.call.bind(Array.prototype.push);
    var pop = Function.prototype.call.bind(Array.prototype.pop);
    
    var a = [1 ,2 ,3];
    push(a, 4)
    a // [1, 2, 3, 4]
    
    pop(a)
    a // [1, 2, 3]

    4. 将Function.prototype.bind方法变成Function.prototype.call的方法,就意味着bind的调用形式也可以被改写

    function f() {
    console.log(this.v);
    }
    
    var o = { v: 123 };
    var bind = Function.prototype.call.bind(Function.prototype.bind);
    bind(f, o)() // 123
  • 相关阅读:
    提示35. 怎样实现OfTypeOnly<TEntity>()这样的写法
    (翻译)Entity Framework技巧系列之十
    Entity Framework教程(第二版)
    实战 ASP.NET Web API
    Apache,PHP,MySQL的安装,配置
    Apache配置虚拟目录和多主机头
    web.config配置详细说明
    百度UEditor编辑器使用教程与使用方法
    若要调试此模块,请将其项目生成配置更改为“调试”模式。若要取消显示此消息,请禁用“启动时若没有用户代码则发出警告”调试器选项
    jquery筛选器
  • 原文地址:https://www.cnblogs.com/gaoguowen/p/10444803.html
Copyright © 2011-2022 走看看