对this对象的理解
1.对this对象的理解
this是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。
下面使用几个例子来说明“最后一次调用”
例1
var name = 'windowsName'
function a() {
var name = 'Jack';
console.log(this);
console.log(this.name)
}
a();
console.log(this)
//Window
//windowsName
//Window
最后调用a的地方是a(),前边没有调用这个函数的对象,因此this指向的是Window全局对象
例2
var name = "windowsName";
var a = {
name: "Jak",
fn: function () {
console.log(this.name);
}
}
a.fn()
//Jack
fn是对象a调用的,所以this指向的是a
例3
var name = "windowsName";
var a = {
name: "Jack",
fn : function () {
console.log(this.name);
}
}
window.a.fn();
//Jack
虽然在a.fn()前加了window.,但最后一次调用fn的还是a对象,所以this指向的也是a
例4
var name = "windowsName";
var a = {
name: "Jack",
fn: function () {
console.log(this.name)
}
}
var f = a.fn
f()
//windowsName
将a对象的fn方法赋值给变量f,但是并没有调用,最后一次调用fn()的还是Window对象,所以this指向的是Window
上述判断this指向的四个例子可以总结为:当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象;如果一个函数作为一个对象的方法来调用时,this指向这个对象,并且指向的是最后调用这个函数的对象。
2.改变this指向的方法
- 使用 ES6 的箭头函数
- 在函数内部使用 _this = this
- new 实例化一个对象
- 使用 apply、call、bind
(1) 箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined
箭头函数不会创建自己的this, 所以它没有自己的this,不会被new调用。它只会从自己作用域的上一层继承this,所以箭头函数的this指向外层函数的this。箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
例5
var name = "windowsName";
var a = {
name : "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
setTimeout( () => {
this.func1()
},100);
}
};
a.func2()
// Cherry
如果不使用箭头函数,结果会报错,其原因是使用普通函数时,最终调用setTimeout的对象是Window,而Window中没有func1函数
(2)如果想不通过箭头函数,解决this指向错误的问题,可以先将func2的this赋值给一个变量_this
例6
var name = "windowsName";
var a = {
name : "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
var _this = this;
setTimeout( function() {
_this.func1()
},100);
}
};
a.func2()
// Cherry
这个例子中,在 func2 中,首先设置 var _this = this;,这里的 this 是调用 func2 的对象 a,为了防止在 func2 中的 setTimeout 被 window 调用而导致的在 setTimeout 中的 this 为 window。我们将 this(指向变量 a) 赋值给一个变量 _this,这样,在 func2 中我们使用 _this 就是指向对象 a 了。
(3)如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象
new操作符的执行过程:
- 首先创建了一个新的空对象(创建一个新的内存空间);
- 设置原型,将对象的原型设置为函数的 prototype 对象;
- 让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性);
- 返回新对象(所以构造函数不需要return)。
因此,使用 new 实例化对象,构造函数中的this指向实例化对象。
(4)使用apply、call和bind指定调用函数的this指向
例7
var name = 'windowsName'
var a = {
name: "Cherry",
func1: function () {
setTimeout(function () {
console.log(this.name)
}, 100);
}
};
a.func1()
//windowsName
例8 使用apply函数
var a = {
name: "Cherry",
func1: function () {
setTimeout(function () {
console.log(this.name)
}.apply(a), 100);
}
};
a.func1()
//Cherry
例9 使用call函数
var a = {
name: "Cherry",
func1: function () {
setTimeout(function () {
console.log(this.name)
}.call(a), 100);
}
};
a.func1()
//Cherry
例10 使用bind函数
var a = {
name: "Cherry",
func1: function () {
setTimeout(function () {
console.log(this.name)
}.bind(a)(), 100);
}
};
a.func1()
//Cherry
apply() 方法调用一个函数,接收两个参数:一个是 this 绑定的对象,一个是参数数组(或类似数组的对象)提供的参数
其语法是:fun.apply(thisArg,[argsArray]),
需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
call()函数的调用方法和apply()函数类似,区别在于call()中的参数是若干个参数列表,传递给函数的参数必须逐个列举出来,例如
fun.apply(a,[1,2])
fun.call(a,1,2)
bind()返回值是新函数,我们必须要手动去调用,新函数也能当做构造函数(
new)调用fun.bind(a,1,2)()

浙公网安备 33010602011771号