zoukankan      html  css  js  c++  java
  • JavaScript this

    this用的很多,react 的class component用了这么多自己也比较熟悉的了,下面就来讲讲如何判断一个this的绑定以及call、apply、bind的实现。

    判断this绑定

    主要就是以下的几点:

    1. 由new调用:绑定到新创建的对象上面。在类里面的contructor中,指向将要通过构造器创建的对象。
    2. 由call、apply、bind来调用,绑定到指定的对象上面。
    3. 由上下文对象调用,就绑定到上下文的对象上面。
    4. 默认:全局对象,node为global,浏览器为window

    如何实现call

    Function.prototype.call = function(context) {
      var context = Object(context) || window;
      // call是由一个函数调用的,此时this就指向该函数
      context.fn = this;
      var args = [];
      for(let i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']');
      }
      var res = eval('context.fn(' + args + ')');	
      delete context.fn;
      return res;
    }
    
    var obj = {
      a: 1
    }
    
    function print() {
      console.log(this.a)
    }
    print.call(obj);
    

    如何实现apply

    apply与call的最大区别就是,apply仅有第二个参数apply(obj, arguments),且arguments为一个数组,数组里面存放了要传递给调用call方法的函数的参数

    而call则一个一个的接收参数call(obj, argument1, argument2, argument3, ... argumentn)

    Function.prototype.apply = function(context, arr) {
      var context = Object(context) || window;
      context.fn = this;
      var res;
      if(!arr) {
        res = context.fn();
      } else {
        var args = [];
        for(let i = 0; i < arr.length; i++) {
          args.push('arr[' + i + ']');
        }
        res = eval('context.fn(' + args + ')');
      }
      delete context.fn;
      return res;
    }
    
    var obj = {
      a: 1
    }
    function bar(b, c) {
      return {
        a: this.a,
        b: b,
        c: c
      }
    }
    bar.apply(obj, [2,3])
    

    如何实现bind

    Function.prototype.bind = function(context) {
      if(typeof this !== "function") {
        throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
      }
      var self = this;
      var args = Array.prototype.call(arguments, 1);
      var fNOP = function() {};
      var fBound = function() {
        self.apply(this instanceof self ? this :context, args.concat(Array.prototype.slice.call(arguments)));
      }
      fNOP.prototype = this.prototype;
      fbound.prototype = new fNOP();
      return bound;
    }
    
  • 相关阅读:
    python装饰器的作用
    python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用
    安全小测试:介绍一个简单web安全知识测试的网站
    浏览器都知道我们的哪些信息?
    SQL开发技巧(二)
    如何解决SQLServer占CPU100%
    记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题
    如何在SQLServer中处理每天四亿三千万记录
    SqlServer索引的原理与应用
    T-sql语句查询执行顺序
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13928993.html
Copyright © 2011-2022 走看看