一看就懂的this指向问题

 

   最近为了勉励自己对学习到的知识做个总结,最后决定写成博客分享给大家。欢迎大家指正,下面就进入正题。

一、this的指向  


在es5中,this的指向只有在运行的时候才可以确定,也就是说创建的时候并不能确实指向。this永远指向最后调用它的对象。

我们来举例说明:

例子1: 

var a = 1
function test () {
    var a = 2;
    console.log(this.a)         //  1
    console.log(this) //  window
}
test()

直接不带任何引用形式去调用函数,在非严格模式的情况下。this默认就是指向全局对象(浏览器是window,Node中是global),,严格模式下这个this其实是undefined的。

例子2:

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        console.log(this.a)     // 2 
        console.log(this)       // obj
    }
}
obj.fn()


最后调用this的是obj,所以指向的是obj.
这个例子稍微改动就为有坑在喔,下面我们就来稍微改一下。

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        console.log(this.a)     // 1 
        console.log(this)       // window
    }
}
var temp = obj.fn
temp()


这个例子最后调用this的就是window,最后就是window.temp();

例子3:

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        return function() {
            console.log(this.a) // 1
            console.log(this)   // window
        }
    }
}
obj.fn()();

函数柯里化,返回的是一个闭包函数也就是最后调用闭包是window,所以最后this指向window。

例子4:

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        setTimeout(function() {
            console.log(this.a) // 1
            console.log(this)   // window
        })
    }
}
obj.fn()


调用 setTimeout 的对象是 window,所以最后this指向window。

 二.改变this的指向

下面我们来举例说明怎么改变this的指向。

1. 箭头函数

    箭头函数的this始终指向函数定义时的this。

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        setTimeout(() =>{
            console.log(this.a) // 2
            console.log(this)   // obj
        })
    }
}
obj.fn()


箭头函数被非箭头函数包含,最近一层非箭头函数的this就是obj   。


2. _this = this

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        var _this = this;
        setTimeout(function(){
            console.log(_this.a) // 2
            console.log(_this)   // obj
        })
    }
}
obj.fn()

将this保存在临时变量 _this,这样 _this的指向将不会改变。

3. call、bind、apply

- apply的用法:fun.apply(this,[arg1, arg2])
- call的用法:fun.call(this, arg1, arg2)
- bind的用法:fun.bind(this, arg1, arg2)()

apply例子:

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        setTimeout(function(){
            console.log(this.a) // 2
            console.log(this)   // obj
        }.apply(obj))
    }
}
obj.fn()


call例子: 

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        setTimeout(function(){
            console.log(this.a) // 2
            console.log(this)   // obj
        }.call(obj))
    }
}
obj.fn()

bind的例子:

var a = 1;
var obj = {
    a: 2,
    fn: function() {
        setTimeout(function(){
            console.log(this.a) // 2
            console.log(this)   // obj
        }.bind(obj)())
    }
}
obj.fn()


4. new实例一个对象

new这个操作符其实是new了一个新对象出来,this指的就是将要被new出来的新对象。

var a = 1
function Test (a) {
    this.a = a;
}
var b = new Test(2);
console.log(b.a) // 2

   
   
    

猜你喜欢

转载自blog.csdn.net/sinat_34798463/article/details/104968564