this有几种情况(8种)

209 阅读2分钟

注意:this只看调用,不看定义(非箭头函数),this是存在作用域对象中的

this.jpg

1.对象方法

obj.fun()中的this ---> . 前的obj

var obj = {
    name: "lilei",
    getName: function() {
        console.info(this.name)
    }
}
obj.getName(); 
2.构造函数

new Fun()构造函数中的this ---> new创建的新对象

function Student(name) {
   this.name = name;
}
var lilei = new Student("lilei");
3.原型对象

原型对象(prototype)公共方法(fun)中的this ---> 调用公共方法 . 前面的子对象(和第一个其实一样)

function Student(name) {
    this.name = name;
}

Student.prototype.getName = function() {
    console.info(this.name);
}
var lilei = new Student("lilei");
lilei.getName(); // 公共方法getName中的this就是指向lilei
4.3种类型函数

普通函数调用、匿名函数自调、回调函数中的this ---> window;严格模式(use strict)下,this ---> undefined

这三个有一个共同特点:前面既没有 . ,也没有new

  • 普通函数调用
function fun() {
    console.info(this);
}
fun();
var value = 1;
function foo() {
    console.info(value) // 1
    console.info(this) // window
}
function bar() {
    var value = 3;
    foo()
}
bar() ;
  • 匿名函数自调
(function() {
    console.info(this);
})();
  • 回调函数
var arr = [1];
arr.forEach(function() {
    console.info(this)
})
5.DOM事件函数

DOM事件函数中的方法,this指向的是当前的DOM元素对象.等于响应事件events中的currentTarget

button.onclick = function() { console.info(this) } // 这里就是button元素对象
button.addEventerListener("click", function() { console.info(this) }) // 也是button元素对象
6.Vue

Vue中methods中的方法中的this默认都指当前vue组件对象

<button @click="fun">

export default {
    methods: {
        fun(e){ e.target }
    }
}
7.箭头函数

箭头函数中的this指向当前函数之外最近的作用域中的this。只改变this,不改变作用域,箭头函数内部,还是函数作用域

箭头函数底层相当于:.bind()

  • 题目一
var lilei = {
    sname: "Li Lei",
    friends: ["涛涛", "东东"],
    intr: function() {
        this.friends.forEach(function(friend) {
            console.info(`${this.sname} 认识 ${friend}`);
        })
    }
}
/**
    undefined 认识 涛涛
    undefined 认识 东东
**/
lilei.intr();

分析:

  • 调用lilei.intr()方法是,这个方法中的this指向的是 . 前面的对象(情况1)。可以访问到this.friends。也就是lilei.friends;
  • lilei.friends的forEach方法,添加了一个回调。这个回调函数中的this。就指向了window(情况4).所以 this.sname就是undefined

那么如何改呢?

  • 把回调函数,改成箭头函数
var lilei = {
    sname: "Li Lei",
    friends: ["涛涛", "东东"],
    intr: function() { // 注意这里的函数,就不可以改成箭头函数!!!
        this.friends.forEach((friend) => {
            // 这里的this就找到定义时的作用域。也就是intr后面的这个方法
            console.info(`${this.sname} 认识 ${friend}`);
        })
    }
}
/**
    Li Lei 认识 涛涛
    Li Lei 认识 东东
**/
lilei.intr();

因为上面的intr不可使用箭头函数,又不想写function。ES6提供了一个方法

var lilei = {
    intr() { // 等同于 intr: function() {}
        console.info(this);
    }
}
8.call、apply、bind
  • 可以使用call或者apply临时替换一次函数中的this
  • 可使用bind永久替换函数中的this
  • 不可修改箭头函数中的this