es5中的this
this是javascript中的一个关键字,它代表函数运行时,自动生成一个内部对象,只能在函数内部使用.
es5中的this是变化的 ,它指向是一大难点, 记住 : this指向调用它的那个对象
面试题中进行分析
全局调用 , this指向global
var name = 'global';
function a(){
var name = 'fun';
console.log(this.name);
}
a();
//global
//虽然函数内部有一个name变量,但是函数是在全局调用,所以是指向全局对象中的name
用call改变 , this指向
var name = 'global';
function a(){
var name = 'fun';
console.log(this.name);
}
obj = {
name:'obj'
}
a.call(obj);
//obj
//可以用call,apply,bind改变this指向的对象
作为方法的调用
var name = 'global';
var obj = {
name : 'obj',
thisName : function(){
var name = 'fun';
console.log(this.name);
}
}
obj.thisName();
//obj
闭包
var name = 'global';
var obj = {
name : 'obj',
thisName : function(){
return function s(){
console.log(this.name)
}
}
}
obj.thisName()();
//global
//方法中的闭包将s()函数弹出到全局环境栈中,所以函数执行this指向global
作为函数构造器调用
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象
var x = 2;
function test(){
this.x = 1;
}
var o = new test();
alert(o.x) //1 this指向
alert(x); //2 验证,全局变量没有改变
es6中this在箭头函数中的使用
箭头函数中没有this , 它的this是继承而来
默认指向它所处的对象(在定义this时就已经确定this指向)
箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this
es5中的定时器
定时器函数中,没有默认的宿主对象,所以默认this指向window
(1)普通函数
var name = 'global';
var obj = {
name : 'obj',
say : function(){
console.log(this.name)
}
}
obj.say()
//obj
(2)定时器
var name = 'global';
var obj = {
name : 'obj',
say : function(){
setTimeout(function(){
console.log(this.name)
},300)
}
}
obj.say()
//global
(3)解决方案1:找个变量保存this
var name = 'global';
var obj = {
name : 'obj',
say : function(){
//由于setTimeont中this指向window,所以需要找一个变量存储一下this
var that = this;
setTimeout(function(){
console.log(that.name)
},300)
}
}
obj.say()
//obj
(4)解决方案2:func.bind(this) 给回调函数直接绑定宿主对象
var name = 'global';
var obj = {
name : 'obj',
say : function(){
setTimeout(function(){
console.log(this.name)
}.bind(this),300)
}
}
obj.say()
//obj
(5)解决方案3:es6中箭头函数解决定时器this指向
var name = 'global';
var obj = {
name : 'obj',
say : function(){
setTimeout(()=>{
console.log(this.name)
},300)
}
}
obj.say()
//obj
验证成果
window.val = 1;
var obj = {
val: 2,
dbl: function () {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
}
};
// 说出下面的输出结果
obj.dbl();
var func = obj.dbl;
func();
//2 4 8 8