最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JavaScript深入之 this和apply、call、bind

    正文概述 掘金(VC橙)   2021-02-24   565

    之前我们说过this是在运行时进行绑定的,并不是在编写时绑定。JavaScript的this总指向一个对象,具体指向哪一个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。

    this的指向大致可以分为下面几种:

    • 1、作为对象的方法调用,this指向该对象
    • 2、作为普通函数,this指向window
    • 3、构造器调用,this指向返回的这个对象
    • 4、箭头函数,箭头函数的this绑定的是this所在函数定义在哪个对象下,就绑定哪个对象,如果也有嵌套的情况,则this绑定到最近一层对象上

    关于箭头函数this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

    作为对象的方法调用

    var obj = {
      a: 1,
      getA: function() {
        console.log(this === obj)  // true
        console.log(this.a) // 1
      }
    }
    obj.getA()
    

    构造器调用

    var MyClass = function() {
      this.name = 'sven'
    }
    var myclass = new MyClass()
    console.log(myclass.name) // 'sven'
    

    隐式绑定

    对象属性引用链中只有上一层或者说最后一层在调用位置中起作用,foo中的this会指向最近一层的obj2

    function foo() {
      console.log(this.a)
    }
    var obj2 = {
      a: 42,
      foo: foo
    }
    var obj1 = {
      a: 42,
      obj2: obj2
    }
    obj1.obj2.foo() // 42
    

    改变this的指向

    • 1、使用es6的箭头函数
    • 2、在函数内部使用that = this
    • 3、使用apply,call,bind
    • 4、new实例化一个对象

    通过apply和call改变函数的this指向,第一个参数都是要指向的this,如果为null函数体内的this会指向默认宿主对象,在浏览器中则是window。第二个参数,apply是数组或者类数组,而call则是arg1,arg2...这种形式。

    如何实现一个call、apply

    var foo = {
        value: 1
    };
    
    function bar() {
        console.log(this.value);
    }
    
    bar.call(foo); // 1
    

    从上面代码可以看出,call改变了this的指向,指向了foo,bar函数执行了。上面我们提到过作为对象的方法调用,this会指向这个对象,因此也可以拿到这个对象的属性。因此我们可以利用这个原理来实现call:

    • 1、将函数设为对象的属性
    • 2、执行该函数
    • 3、删除该属性
    Function.prototype.call = function (context) {
      var context = Object(context) || window;  // 第一个参数为null指向window
      context.fn = this;
    
      var args = [];
      for (var i = 1, len = arguments.length; i < len; i++) { // 获取call后面的参数
        args.push('arguments[' + i + ']');
      }
    
      var result = eval('context.fn(' + args + ')'); // 依次将参数放到方法中执行
    
      delete context.fn
      return result;
    }
    

    如何实现一个bind

    bind 会返回一个函数,并不会立即执行 第二个是带参数(第一个参数要指向的this,后面的的参数用来传递)

    Function.prototype.bind2 = function (context) {
        var self = this;
        
        // 获取bind2函数从第二个参数到最后一个参数
        var args = Array.prototype.slice.call(arguments, 1);
    
        var fbound = function () {
            self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
        }
        return fbound;
    }
    

    起源地下载网 » JavaScript深入之 this和apply、call、bind

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元