this的指向
this指向的原则:始终指向最后调用它的对象
看个简单的例子:
var name = "wN";
function fn() {
var name = "Jack";
console.log(this.name); // wN
}
fn();
根据this指向原则:始终指向最后调用它的对象,最后调用fn()这里,前面没有调用的对象那么就是全局对象 window,所以相当于window.fn()
接着看例子:
var name = "wN";
var a = {
name: "Jack",
fn : function () {
console.log(this.name); // Jack
}
}
a.fn();
在这里,函数 fn 是对象 a 调用的,所以打印的值就是 a 中的 name 的值,对this是不是有了初步的认识。
var name = "wN";
var a = {
name: "Jack",
fn : function () {
console.log(this.name); // Jack
}
}
window.a.fn();
这里打印的也是Jack,还是因为this指向原则,window.a.fn()最后调用的对象是a,this指向a对象中的name。
改变this的指向
改变this的指向有几种方法:
- 在函数内部使用 _this = this
- 使用 apply、call、bind
- 使用 ES6 的箭头函数
- new 实例化一个对象
下面逐一展开说说
使用 _this = this
var a = {
name : "Jack",
func1: function () {
console.log(this.name)
},
func2: function () {
var _this = this;
setTimeout( function() {
// this.fun1() // this.fun1 is not a function
_this.func1() // Jack
},100);
}
};
a.func2() // Jack
我们是先将调用这个函数的对象保存在变量中,然后在函数中都使用这个变量var _this = this,这是最简单的方式。
使用apply、call、bind
apply
var a = {
name : "Jack",
func1: function () {
console.log(this.name)
},
func2: function () {
setTimeout( function () {
this.func1()
}.apply(a),100); //call同理
}
}
a.func2() // Jack
bind
var a = {
name : "Jack",
func1: function () {
console.log(this.name)
},
func2: function () {
setTimeout( function () {
this.func1()
}.bind(a)(),100);
}
}
a.func2() // Jack
apply、call、bind 区别
apply 和 call 类似,只是两者之间传递的参数不同。
apply(thisArg, argsArray)
call(thisArg, arg1, /* …, */ argN)
都是两个参数,第一个参数两者都为this调用时使用的值func,第二个参数,apply是数组,call是参数列表,直接传。
var a ={
fn : function (a,b) {
console.log(a,b)
}
}
var b = a.fn;
b.apply(a,[1,2]) // 1,2
var a ={
fn : function (a,b) {
console.log(a,b)
}
}
var b = a.fn;
b.call(a,1,2) // 1,2
bind函数创建一个新的绑定函数,同时它的参数如下:
bind(thisArg, arg1, arg2)
第一个参数两者都为`this`调用时使用的值`func`,第二个参数是参数列表
var a ={
fn : function (a,b) {
console.log(a,b)
}
}
var b = a.fn;
// b.bind(a,1,2) // 无输出
b.bind(a,1,2)() // 根据bind会创建一个新的绑定函数,所以需要手动调用
箭头函数
ES6箭头函数里this指向外层,也就是上一层
var obj = {
num: 10,
fn: function () {
console.log(this); // obj
setTimeout(function () {
console.log(this); // window
});
}
}
obj.fn()
在上面的例子中,第一个this指向obj,因为fn的调用者是obj,而setTimeout里是匿名函数,没有直接调用者,所以this指向window。
var obj = {
num: 10,
fn: function () {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
});
}
}
obj.fn();
第一个this指向obj,setTimeout箭头函数,this指向外层,所以也是obj
new 实例化一个对象
直接看例子:
function fn(){
console.log(this);
}
fn(); // window
let obj=new fn(); // fn()
使用new实例化对象时,this代表被实例化的对象。
这就是this的指向,当然,也有复杂的场景,这里就不去过多的讲解了,用简单的例子带你认识 this 同时希望我的文章能对你有所帮助,有什么不对的地方可以评论指出。