一、this的指向问题
this指向调用者。
1. 普通函数的this => window
function fn() {
console.log(this);
}
fn(); // this => window
2. 立即执行函数的this => window
(function() {
console.log(this); // this => window
})();
3. 定时器函数的this => window
setInterval(function() {
console.log(this); // this => window
}, 1000);
setTimeout(function() {
console.log(this); // this => window
}, 1000);
4. 对象中的函数的this => 该方法所属的对象
var obj = {
fn: function() {
console.log(this); // this => obj
}
};
obj.fn();
5. 构造函数的this => 创建的实例对象
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this); // 这里打印的this分别指向 Person 的实例对象 p1 p2
};
var p1 = new Person('张三', 18);
var p2 = new Person('李四', 20);
6. 事件函数的this => 事件函数的事件源
<body>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function() {
console.log(this); // this => btn
}
</script>
</body>
7. 箭头函数的this => 箭头函数没有自己的this,它的this指向上下文对象
let obj = {
say() {
console.log('我是say:', this);// this => obj
},
walk() {
setTimeout(function () {
console.log('我是walk:', this);// this => window
}, 100);
},
run() {
setTimeout(() => {
console.log('我是run:', this);// this => obj
},100);
}
}
obj.say();
obj.walk();
obj.run();
二、更改this的三个方法
1. call() 方法
var Person = {
name: "张三",
age: 19
}
function fn(x,y) {
console.log(x + "," + y);
console.log(this);
console.log(this.name);
}
fn(4, 5); // this指向window; 4,5 window undefined
fn.call(Person, 4, 5); // this指向Person; 4,5 Person{}对象 张三
2. apply() 方法
apply() 与 call() 非常相似,都是立即执行, 不同之处在于提供参数的方式, apply() 使用参数数组, 而 call() 是参数列表
var Person = {
name: "张三",
age: 20
}
function fn(x,y) {
console.log(x + "," + y);
console.log(this);
console.log(this.name);
}
fn.apply(Person, [4, 5]); // this指向Person; 4,5 Person{}对象 张三
3. bind() 方法
bind() 方法 不能立即执行,必须要调用一次,才能执行
var Person = {
name: "张三",
age: 20
}
function fn(x,y) {
console.log(x + "," + y);
console.log(this);
console.log(this.name);
}
fn.bind(Person, 4, 5); // 只是更改了this指向,没有输出
fn.bind(Person, 4, 5)(); // this指向Person; 4,5 Person{}对象 张三