美文网首页
JavaScript中的this

JavaScript中的this

作者: 海山城 | 来源:发表于2017-12-06 11:35 被阅读0次

    JS中的this指的是什么?

    JS中的this的含义非常多,可以是全局变量,当前对象,或者任意对象,这取决于函数的调用方式
    无论怎么变,但是有个总的原则,this指的是调用函数的那个对象

    JS函数的调用形式

    JS(ES5)里面有三种函数调用形式:

    func(p1, p2) 
    obj.child.method(p1, p2)
    func.call(context, p1, p2) // 先不讲 apply
    

    一二两种形式其实是第三种调用形式的语法糖,等价于

    func.call(undefined, p1, p2) 
    obj.child.method.call(obj.child, p1, p2)
    

    所以第三种形式才是JS的正常的调用形式,套用这种形式理解this就容易多了,this就是指的上面代码中的context

    作为函数调用或者对象方法调用中的this

    var obj = {
      foo: function(){
        console.log(this)
      }
    }
    
    var bar = obj.foo
    obj.foo() // 打印出的 this 是 obj
    bar() // 打印出的 this 是 window
    

    通过上一节的函数的调用形式来理解
    (1) 先来看看bar()的结果是window

    bar()  等价于
    bar.call(undefined)// 可以简写为 bar.call()
    

    按理说this应该是undefined啊,是这样的,浏览器里有一条规则

    如果你传的 context 是 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

    所以bar() 打印出的 this 是 window,如果不想是window,很简单

    bar.call(obj) // 那么里面的 this 就是 obj 对象了
    

    (2) 再来看obj.foo()结果就更容易理解了

    obj.foo()  等价于
    obj.foo.call(obj)
    

    所以obj.foo()打印出的 this 是 obj

    (3) 上面两种形式已经会转换成func.call(context, p1, p2)形式了,那么看看下面这种[ ] 语法怎么转换

    function fn (){ console.log(this) }
    var arr = [fn, fn2]
    arr[0]() // 这里面的 this 又是什么呢?
    

    将arr[0]( )想象为arr.0( ),虽然后者的语法错了,但是形式容易转换

    arr.0.call(arr)
    

    那么里面的this就是arr了

    setTimeout、setInterval中的this

    document.addEventListener('click', function(e){
        console.log(this);        //this指的是document
        setTimeout(function(){
            console.log(this);    //this指的是window
        }, 200);
    }, false);
    

    setTimeout、setInterval中的this指的是window

    作为构造函数调用中的this

    var _this1, _this2, _this3, this4
    function person(name, age){
      this.name = name
      this.age = age
      _this1 = this
    }
    person.prototype.printName = function(){
      _this2 = this
    }
    
    function male(name, age, sex){
      person.call(this, name, age)
      this.sex = sex
      _this3 = this
    }
    
    male.prototype = Object.create(person.prototype)
    male.prototype.printSex = function(){
      _this4 = this
    }
    male.prototype.constructor =  male
    
    var m = new male('hsc', 25, 'man')
    m.printSex()
    m.printName()
    console.log(_this1 === m) //true
    console.log(_this2 === m) //true
    console.log(_this3 === m) //true
    console.log(_this4 === m) //true
    
    var p = new person('Li',30)
    p.printName()
    console.log(_this1 === p) //true
    console.log(_this2 === p) //true
    

    从上面的例子可以看出,构造函数中的this,无论是构造函数上的,还是原型链上的,指的都是通过该函数构造出来的那个实例对象

    DOM对象绑定事件中的this

    document.addEventListener('click', function(e){
        console.log(this); //document
    }, false);
    

    在事件处理程序中的this指代的是绑定事件的DOM对象
    值得注意的是: jquery的事件代理中的this,jquery事件代理中的this指的的点击的DOM元素,而不是绑定事件的DOM元素,这点与原生JS相反
    jquery

    $('ul').on('click', 'li', function(){
      console.log(this)//点击每个li,显示的结果是每个li
    })
    

    原生JS

    document.querySelector('ul').onclick = function(){
      console.log(this)//点击每个li,显示的结果都是ul
    }
    

    最后,this也是可以改变的,改变this的方法见下一篇改变this的方法

    相关文章

      网友评论

          本文标题:JavaScript中的this

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