注意:this只看调用,不看定义(非箭头函数),this是存在作用域对象中的
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