this指向问题
this:函数执行的主体(谁执行的函数)
- 事件绑定
- 函数执行 [普通函数执行,成员访问,匿名函数,回调函数...]
- 构造函数
- 箭头函数 [生成器函数generator]
- 基于call/apply/bind强制修改this指向
事件绑定
-
DOM0:xxx.onclick = function(){}
-
DOM2:
- xxx.addEventListener('xxx',function(){})
- xxx.addachEvent('onclick',function(){}) // IE6~8
给元素的某个事件行为绑定方法「DOM0 & DOM2」,当事件行为触发,方法执行,方法中的THIS是当前元素本身
判断this技巧
函数执行,看方面前面是否有“点”
@1 有“点”:“点”前面是谁,THIS就是谁
@2 没有“点”:方法中的THIS是window(非严格模式)/undefined(严格模式)
@3 立即执行函数this指向window/undefined
例题
var num = 10; //=>65
var obj = {
num: 20 //=>30
};
obj.fn = (function (num) {
this.num = num * 3;
num++; //=>21
return function (n) {
this.num += n;
num++;
console.log(num); //=>22 23
}
})(obj.num);
var fn = obj.fn;
fn(5);
obj.fn(10);
console.log(num, obj.num); //65 30
let obj = {
fn: (function () {
return function () {
console.log(this);
}
})()
};
obj.fn(); //=>obj
let fn = obj.fn;
fn(); //=>window
/*
obj.prop调用指向obj.prop
*/
var fullName = 'language';
var obj = {
fullName: 'javascript',
prop: {
getFullName: function () {
return this.fullName;
}
}
};
console.log(obj.prop.getFullName()); //=>undefined
var test = obj.prop.getFullName;
console.log(test()); //=>language
var name = 'window';
var Tom = {
name: "Tom",
show: function () {
console.log(this.name);
},
wait: function () {
var fun = this.show;
fun();
}
};
Tom.wait(); //=>window
window.val = 1;
var json = {
val: 10,
dbl: function () {
this.val *= 2;
}
}
json.dbl(); //=>20
var dbl = json.dbl;
dbl(); //=>2
json.dbl.call(window); //=>4
alert(window.val + json.val); //=>24
(function () {
var val = 1;
var json = {
val: 10,
dbl: function () {
val *= 2; //=>2
}
};
json.dbl();
alert(json.val + val); //=>12
})();
var x = 3,//=>12 13 234
obj = {
x:5 //=>95
};
obj.fn = (function (){
this.x *= ++x;
return function (y){
this.x *=(++x) + y;
console.log(x) //13 234
}
})();
var fn = obj.fn;
obj.fn(6);
fn(4);
console.log(obj.x,x); //95 234
/*
注意:函数才是谁调用this指向谁
*/
var obj = {
a: 10,
b: this.a + 10, //这里的this指向window(全局),a为undefined ==> undefined + 20 = NaN
fn: function () {
return this.a;
}
}
console.log(obj.b); //NaN
console.log(
obj.fn(), //10
obj.fn //fn
);
var a = 5;
function fn1(){
var a = 6;
console.log(a); //6
console.log(this.a); //5
}
function fn2(fn) {
var a = 7;
fn();
}
var obj = {
a: 8,
getA: fn1
}
fn2(obj.getA);
var obj = {
foo: "test",
fn: function(){
var mine = this;
console.log(this.foo); //test
console.log(mine.foo); //test
(function(){
console.log(this.foo); //undefined
console.log(mine.foo); //test
})();
}
};
obj.fn();
function foo(){
console.log(this.a);
}
var a = 2;
var o = {
a:3,
foo: foo
};
var p = { a:4 };
o.foo(); //3
//
(p.foo = o.foo)(); //=>2
p.foo = o.foo;
p.foo(); //=>4
function test(arg) {
this.x = arg;
return this;
}
var x = test(5);
var y = test(6);
console.log(x.x); //=>相当于window下的window undefined
console.log(y.x); //=>6
var obj = {
data: [1,2,3,4,5],
data2: [1,2,3,4,5],
fn: function () {
console.log("--test--");
console.log(this);
return this.data.map(function (item) {
console.log(this);
return item * 2;
});
},
fn2: function () {
console.log("---test2---");
console.log(this);
return this.data2.map(item=>{
console.log(this);
return item * 2;
});
}
};
obj.fn();
obj.fn2();