美文网首页菜鸟朱茱霞的前端搬砖史
javaScript函数基础总结(1)声明/调用/this

javaScript函数基础总结(1)声明/调用/this

作者: 朱珠霞 | 来源:发表于2018-05-30 19:15 被阅读9次

    函数是什么?

    函数是一种特殊的对象,也是由事件驱动或者被调用时执行的可重复使用的代码块。

    函数的几种声明方式

    function fn1(input1,input2){
    console.log(fn1.name)
    }//具名函数声明
    
    function(){
     console.log('我没有name属性')
    }//匿名函数声明,一般不单独使用
    
    var x = function fn3(input1,input2){
     console.log(fn3.name)
    }// 变量赋值方式
    console.log(x.name) //'fn3'
    console.log(fn3.name)//报错,fn3没有定义。
    
    var y = new Function ('x','y','return x+' + n + '+y')
    //函数对象构造声明
    //除最后一个参数是函数体外,其他都是参数
    
    f(x,y) =>{console.log('我是匿名函数,没有name属性')}
    //ES6新语法
    
    • 创建匿名函数可以避免命名冲突。
    • 匿名函数创建完成后,在堆内存(heap)内存上地址,被变量引用才能被使用。
    • 或者匿名函数在创建完成后直接调用。(这个用法在MVC中js模块中常被使用。)

    函数的调用

    function callfn(){
      console.log('我被调用了')
    }
    //第一种调用方式,语法糖
    callfn()
    //第二种调用方式,call()
    callfn.call(undefined,argument1,argument2)
    //第三种调用方式,apply()
    callfn.apply(undefined,[argument1,argument2])
    

    Ⅰ. this

    前面call()apply()的调用方法,第一个参数就是this。
    在我接触this的一段时间里,this是一个捉摸不透的玩意。很多时候一不小心加了几个代码,就改变了this的指向,而我却毫不知情。所以对this做一个总结是很有必要的。
    为了了解this,我翻看了好多篇技术博客,有一篇博客我觉得形容this很贴切。

    this是某个函数运行时的上下文(context),call()、apply()的存在就是为了改变函数体内部 this 的指向。
    而JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

    1.this首先肯定是一个对象。
    2.this是函数与对象的羁绊。
    3.this就是这个嵌有这个函数的对象。
    几个典型的小李子:

    • 第一个小李子
    function obj(){
        var a = 1
        console.log(this.a)
    }
    var a = 2
    obj() //2
    //在这个例子里,obj是一个全局变量函数。
    //它被包含在window对象,所以我们可以理解为它的this就是window。
    //但要注意的是!!如果在严格模式下,this会指向undefined!
    
    • 第二个小李子
    var obj = {
        a: 2,
        fn1: function (){
        var a = 1
        console.log(this.a)
        }
    }
    obj.fn1() //2
    //在这个例子里,可以看出fn1是obj的其中一个方法函数,
    //这里的this就是包含fn1这个函数的上一级对象----obj。
    
    • 第三个小李子
    function fn1(){
        var a = 1
        console.log(this.a)
    }
    var obj = {
        a: 2,
        fn1:fn1
    }
    fn1() //undefined
    obj.fn1() //2
    /** 在这个例子里,两种不同的调用方法,产生的结果却完全不同
      *因为同样一个函数地址,它却被两个不同的变量所引用。
      *第一个fn1()被调用在全局环境下调用,而在全局对象window里,a没有赋值,因此结果为undefined
      *第二个obj.fn1()的调用是在对象obj环境下调用,因此指向obj.a===2
      *这种方法是隐式绑定
    **/
    
    • 第四个小李子
    function obj(a){
        this.a = a
    }
    var fn1 = new obj(2)
    console.log(fn1.a) //2
    //使用new构造函数,this指定的都是构造出来的新对象。
    
    • 第五个小李子
      另外,在dom的事件触发和事件监听中,函数内的this指向是用户所触发事件的元素。jQuery的事件监听同理,如果是事件委托,则与selector相匹配的元素。

    • 第六个小李子
      箭头函数内外this不变,因为箭头函数没有this


      即使使用了call()方法,赋值this,最终打印出来的箭头函数的this是window。
      那么我们在实际开发的时候,碰到有事件监听的情况下可以使用这个特性不改变this:
    !function(){
    var view = document.querySelector('#targetElement')
    var controller = {
      view: null,
      init: function(){
        this.view = view
        this.bindEvents()
      }
      bindEvents:function(){
            window,onscroll(()=>{
            console.log(this.view)
        })
      }
    }
    
    

    以上是在没有使用call()apply()情况下,this的指向判断,但当使用过了call()apply()后,this的指向明显清晰了,因为我们可以根据自己的意愿随意更改this!

    Ⅱ.call()apply()bind()

    • call()apply()

      1. 两者用法相似,都是调用函数体及改变函数体内的this指向.
      2. 不同的是,apply()传入的参数是一个数组,通常在执行可变参数的函数时可以使用apply(),将每个参数传入一个数组。
        调用方法如下:
        fn.call(this,arg1,arg2)
        fn.apply(this,[arg1,arg2)
      3. 改变this的一个简单例子
    • bind()
      bind() 允许我们在函数或者方法被调用时绑定 this 到指定对象上。
      例如:在js的DOM事件里,当某一事件被调用时,this会默认是事件调用的Node对象身上,此时我们可以使用bind()函数,绑定一个回调函数,改变this的指向。
      一个简单的小李子

    • 总结

    1. callapplybind都可以改变函数的this对象的指向。
    2. callapplybind除了第一个参数是this指向外,后面可以继续传参数。
    3. bind是返回回调函数,不是立即调用,而applycall是立即调用。

    相关文章

      网友评论

        本文标题:javaScript函数基础总结(1)声明/调用/this

        本文链接:https://www.haomeiwen.com/subject/abpzjftx.html