js中的this指向汇总
1. 事件中的this:给谁添加的事件this就指向谁
// html代码
<div id="box" style="border: 1px solid #000; width: 300px; height: 300px;">
<button id="btn1">按钮1</button>
</div>
// js代码
var btn1 = document.getElementById("btn1");
var box = document.getElementById("box");
box.onclick = function(e){
console.log(this); // box
this.innerHTML = "你猜我里面还有按钮吗";
}
2. 对象中的this:指向调用者
var username = "zhangsan";
var user = {
username:"lisi",
getName:function(){
console.log(username);// zhangsan //没有添加任何前缀,默认是window.
console.log(window.username);// zhangsan
console.log(this.username);// lisi
// this.username 相当于 user.userName
// 对于这个函数来说调用者是user,所以this指向user
}
};
user.getName(); // 函数调用
3. 闭包中的this:永远指向window,也可赋值给that来改变this指向
var name = "lisa";
var user = {
name:"zs",
getName:function(){
return function(){
// 闭包中的this指向window
console.log(this.name);
}
}
}
var fn = user.getName();
fn(); //lisa
var nickname = "昵称";
var appUser = {
nickname:"昵称1",
getNickname:function(){
// that改变this指向
var that = this;
return function(){
console.log(that.nickname);
}
}
}
var fn1 = appUser.getNickname();
fn1(); // 昵称1
4. 定时器中的this指向window,也可赋值给that来改变this指向
var name = 'zs';
var user = {
name: 'lisi',
getName:function(){
setTimeout(() => {
// 定时器中this指向window
console.log(this.name); // zs
}, 1000)
}
}
user.getName();
var name = 'zs';
var user = {
name: 'lisi',
getName:function(){
// that可改变this指向
var that = this;
setTimeout(() => {
// 定时器中this指向window
console.log(that.name); // lisi
}, 1000)
}
}
user.getName();
5. 箭头函数中没有this对象,故箭头函数中的this指向它的上一层
var name = 'zs';
var user = {
name:'lisi',
getName(){
setTimeout(() => {
// 这里若是正常函数,this指向的是window
// 箭头函数中没有this对象,故箭头函数中的this指向它的上一层
console.log(this.name); // lisi
}, 1000);
}
}
user.getName();
6. apply/bind/call可改变this指向
对象A.apply(对象B,arguments) // 对象A中的 this指向 改为 对象B
// apply、call、bind 改变this的指向
var user = {
name:"zs",
getName:function(city){
console.log(this.name,city); // 对象中的this
}
}
var people = {
name:"lisi"
}
// user.getName(); // this本来应该指向user // zs
// call/apply/bind的第一个参数都是this指向
// call:将user对象中的this指向变成people
user.getName.call(people); //lisi
// apply:将user对象中的this指向变成people
user.getName.apply(people); //lisi
// bind: 返回的是一个新的函数,必须在后面加个(),调用它才能执行
user.getName.bind(people)(); //lisi
// 【call/apply的区别】call/apply接收的第二个参数不同,
// call接收基本数据类型,apply接收的数组类型
// 第一个参数是this指向,第二个参数是方法传递的参数
user.getName.call(people,"北京"); // lisi 北京
user.getName.apply(people,["北京"]); // lisi 北京
function Parent(name,age){
// 构造函数中的this指向它的实例化对象
this.name=name
this.age=age
console.log(this)
console.log(this.name,this.age)
}
function Children(name,age,height){
// console.log(this,arguments)
// 这里的this指向Children的实例化对象,所以apply相当于把Parent中的this指向改为了Children的实例化对象了
Parent.apply(this,[name,age,height])
// Parent(name,age)
this.height=height
}
let lisi=new Children("李四",12,170)
console.log(lisi.name,lisi.age,lisi.height)
7. es6类的静态方法中的this指向类,实例方法中的this指向类的实例对象
// 注:如果静态方法包含this关键字,这个this指向类,而不是实例
class People{
static staticSay(){
this.say(); // 这里的this指向People类,所以类名调用的是静态的say方法
}
static say(){
console.log("静态say");
}
say(){
console.log("实例say");
}
}
People.staticSay(); // 静态say
var p1 = new People();
// 实例化对象调用的是实例方法
p1.say(); // 实例say