js⼗种this指向例题汇总(搞定它们js中this指向应该问题不⼤)
1.
var obj ={
a:10,
b:this.a +10,
fn:function(){
return this.a;
}
}
console.log(obj.b);
console.log(obj.fn());
运⾏结果:
obj.b => NaN
obj.fn() => 10
在对象⾥,属性⾥的this指向window,在全局作⽤域没有定义a,但由于是对象.a相当于创建了a,只是没赋值,this.a为undefined,加上⼀个数值,故NaN;⽅法⾥的this指向⽅法的调⽤者,这⾥就是obj对象本⾝,执⾏函数,故得到对象⾥的a值10。
2.
var a =20;
var obj ={
a:10,
getA:function(){
return this.a;
}
}
console.A());
var test = A;
console.log(test());
运⾏结果:
test() => 20
第⼀个输出10不难理解,就是对象⾥的⽅法this指向它的调⽤者obj;var test = A;相当把对象⾥的getA⽅法函数体赋值给test,
即var test = function(){return this.a;}此时this指向window对象,故输出20。
3.
var a =5;
function fn1(){
var a =6;
console.log(a);
console.log(this.a);
}
function fn2(fn){
var a =7;
fn();
}
var obj ={
a:8,
getA: fn1
}
A);
输出结果:
a => 6
this.a => 5
⾸先从fn2函数调⽤开始,这⾥有个实参A,指的是obj对象⾥getA⽅法,⽽getA⽅法是fn1,即相当于在fn2⾥传了fn1函数,由于作⽤域,a输出6,this这⾥指的是window对象,故this.a值为5。
4.
function fn(){
'use strict';
var a =1;
var obj ={
a:10,
c:this.a +20
}
return obj.c;
}
console.log(fn());
输出结果:
fn() => 报错
这个函数体内部是在严格模式下运⾏的,在严格模式下,禁⽌this关键字指向全局对象,对象属性⾥的this指向全局对象window,故会报错。
5.
function Person(name,age){
this.name = name;
this.age = age;
console.log(this);
}
Name=function(){
console.log(this);
}
var p1 =new Person('test',18);
输出结果:
构造函数⾥的this、原型上getName⽅法⾥的this都是指向实例化对象,故结果都是Person这个构造函数。
6.
var obj ={
foo:"test",
fn:function(){
var mine =this;
console.log(this.foo);
console.log(mine.foo);
(function(){
console.log(this.foo);
console.log(mine.foo);
})();
}
};
obj.fn();
输出结果:
第⼀组:test test
第⼆组:undefined test
对象的⽅法⾥this指向⽅法的调⽤者,故第⼀组都是打印obj本⾝的foo属性值,在第⼆组时,由于时⾃执⾏函数,函数体内this指向的是window对象,在全局作⽤域下没有foo属性,故undefined,由于前⾯把this赋值给了⼀个变量保存,所以第⼆组mine.foo还是调⽤对象的属性foo。
7.
function foo(){
console.log(this.a);
}
var a =2;
var o ={
a:3,
foo: foo
};
var p ={
a:4
};
o.foo();
(p.foo = o.foo)();
p.foo = o.foo;
p.foo();
输出结果:
js argumentso.foo() => 3
(p.foo = o.foo)() => 2
p.foo() => 4
o.foo()指访问o对象⾥有个名为foo的⽅法,并执⾏它,这⾥我们知道了,这是对象内的⽅法,this指向o这个对象,故为3;第⼆个是个⾃执⾏函数,它是把对象o的⽅法foo添加到对象p的⽅法中去,但由于此时是个⾃执⾏函数,函数体内this指向window,故为2;第三个也是如同第⼆个,只不过是在是访问对象内的⽅法,此时this指向对象p,故为4.
8.
function foo(){
console.log(this.a);
}
var obj1 ={
a:3,
foo: foo
};
var obj2 ={
a:5,
foo: foo
};
obj1.foo();
obj2.foo();
obj1.foo.call(obj2);
obj.foo.call(obj1);
输出结果:
obj1.foo() => 3
obj2.foo() => 5
function test(arg){
this.x = arg;
return this;
}
var x =test(5);
var y =test(6);
console.log(x.x);
console.log(y.x);
输出结果:
x.x => undefined
y.x => 6
这道题有点意思:⾸先我们分析我们把5这个实参传给了test函数的形参,函数体内this指向window,即在window下添加了⼀个x属性值为5,函数返回这个window对象通过全局变量x接受,但由于此时x也是window对象上的,执⾏x.x时它会覆盖之前window.x=5,现在
是window.x=window,所以它不会向我们想的那样拿到5,⽽是⽆限循环访问window对象;⽽执⾏y =
test(6)时,把6传进去,此时window 对象上的x⼜⼀次被覆盖,现在是window.x=6,通过全局变量y去接受这个返回值window对象,相当于是window.y=window,即此
时window.x=6了,y变为window对象了,可以通过y.x访问到6,⽤x.x访问时全局变量x变成了数值了,故是undefined。
10.
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();
输出结果:
实际这⾥主要是让我们区分箭头函数与普通函数的区别,这⾥是对象,在fn⽅法内this指向调⽤者,故为obj对象,在return语句⾥函数⾥由于window下调⽤了函数,故this指向window,循环输出5次window对象;在fn2⽅法⾥,同理,this指向obj对象,在箭头函数⾥,this 指向靠近的作⽤域,故为obj对象。
这⾥扩展⼀下箭头函数和普通函数的区别吧:
箭头函数体内this对象,是定义时所在的作⽤域中的this值,⽽不是使⽤时所在的对象;
不可以使⽤arguments对象,该对象在函数体内不存在,如果要⽤,可以⽤rest参数(剩余参数)代替;
不可使⽤yield命令,因此箭头函数不能做Generator函数;
不可使⽤new命令:因为没有⾃⼰的this,⽆法调⽤call()、apply();没有prototype属性,⽽new命令在执⾏时需将构造函数的
prototype赋值给新对象__proto__。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论