JS里的函数的四种调用方式及四个this

716 阅读2分钟

老夫写文章,讲究的就是一个字,快,所以很多时候没有清晰的条理结构。平铺直叙,逐条罗列,有兴趣的择条而观之吧。

  1. 在js中,函数是第一型对象,也就是说,函数可以共处,可以将其视为其他任意类型的js对象。就像普通的js数据类型,函数可以被任意变量进行引用,或声明成对象字面量,甚至可以将其作为函数参数进行传递。

  2. 通常我们理解的事件,比如浏览器上的点击事件,并不是立即触发的,而是各种事件会形成一个事件队列保存起来,浏览器通过轮询来唤起这些事件对应的回调函数。

  3. 下面这种函数声明方式其实是匿名函数,匿名函数的重要特征是其name属性为空字符串

    let fn=()=>{
        do sth...
    }
    //fn.name=""
    
  4. 有四种不同的方式可以进行函数调用,每种方式都有自己细微的差别。

    1. 作为一个函数调用

      function fn(){
          do sth
      }
      fn()
      
    2. 作为一个方法调用

      let person={}
      person.eat=function(){
          do sth
      }
      
    3. 作为构造器进行调用

      let person=new People()
      
    4. 通过apply()或者call()方法进行调用

      eat.call(obj,arg)
      
  5. 所有的函数调用都会传递两个隐式参数:argument和this,所谓隐式,也就意味着这些参数不会显示列在函数签名里,但是它们摸摸地传递给函数并存在于函数作用域内。在函数内部,它们可以像其他显式命名的参数一样使用。

  6. this参数引用了与该函数调用进行隐式关联的一个对象,被称之为函数上下文。

  7. 第4点说到了函数的四种调用方式,它们之间的主要差异就是作为this参数传递给执行函数的上下文对象之间的区别。

    • 作为方法进行调用,该上下文是方法的拥有者

    • 作为全局函数进行调用,其上下文永远是window,即使是a函数内声明的b函数,b函数的this也为window

    • 作为构造器进行调用,其上下文对象则是新建的对象实例

    • call()与apply()则可以自由指定函数上下文

      function forEach(list,callback){
          for(var n=0;n<list.length;n++){
              callback.call(list[n],n);
          }
      }
      
      var weapons=[1,2,3]
      
      forEach(weapons,function(index){
          console.log(this)
      })
      
      //1
      //2
      //3