要点
- 函数内部直接调用的函数 this 指向 window
- 箭头函数的 this 指向是在声明时就确定了的,不会被更改
- new 出来的函数的 this 指向是实例对象
- bind 和箭头函数优先级较高
练习题
1
var obj = {
a: 10,
b: this.a + 10,
fn: function () {
return this.a;
},
};
console.log(obj.b);
console.log(obj.fn());
- 答案
// NaN 对象里面没有this指向,对象里面的this指向和它所在的作用域保持一致。指向window
// 10 obj. 时指向obj 指向obj
2
var a = 20;
var obj = {
a: 10,
getA: function () {
return this.a;
},
};
console.log(obj.getA());
var test = obj.getA;
console.log(test());
- 答案
// 10 obj. 指向obj
// 20 在window中调用,指向window
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,
};
fn2(obj.getA);
- 答案
// 6 跟指向无关,作用域问题
// 5 指向window
4
function fn() {
var a = 1;
var obj = {
a: 10,
c: this.a + 20,
};
return obj.c;
}
console.log(fn());
- 答案
// NaN 指向window
5
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this);
}
Person.prototype.getName = function () {
console.log(this);
};
var p1 = new Person('test', 18);
p1.getName();
var p2 = p1.getName;
p2();
- 答案
// Person {name: 'test', age: 18} 指向Person实例对象
// Person {name: 'test', age: 18} 指向Person实例对象
// window 指向window
6
var obj = {
foo: 'test',
fn: function () {
var mine = this;
console.log(this.foo);
console.log(mine.foo);
var fun = function () {
console.log(this.foo);
};
fun();
(function () {
console.log(this.foo);
console.log(mine.foo);
})();
},
};
obj.fn();
- 答案
// test obj. 指向obj
// test obj. 指向obj
// undefined 方法的内部函数的this指向window
// undefined 方法的内部函数的this指向window
// test obj. 外部存this 指向obj
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();
- 答案
// 3 obj. 指向对象o
// 2 赋值后返回的是赋上的值 指向window
// 4 obj. 指向对象p
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);
obj2.foo.call(obj1);
- 答案
// 3 obj. 指向对象obj1
// 5 obj. 指向对象obj2
// 5 call 被修改this指向到obj2
// 3 call 被修改this指向到obj1
9
function test(arg) {
this.x = arg;
console.log(this);
return this;
}
var x = test(5);
var y = test(6);
console.log(window.x.x);
console.log(y.x);
- 答案
// window
// window
// undefined
// 6
-
解析
- 首先执行了
var x = test(5);,这个过程中先将 window 中的 x 置为了 5,然后将 window 中的 x 置为了 window 对象;此时window.x = window; - 然后执行了
var y = test(6);,这个过程将 window.x 设置成了 6,然后将 y 设置成了 window;此时window.x = 6,y = window; - 所以
windwo.x.x也就是6.x为 undefined,y.x也就是window.x为 6
- 首先执行了
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();
- 答案
// obj obj. 指向obj
// window * 5 函数内调用函数指向window
// obj obj. 指向obj
// obj * 5 箭头函数 指向外部this
11
function func(num) {
this.count++;
}
func.count = 0;
func(1);
console.log(func.count);
- 答案
// 0 func被调用时指向window和func.count没有关系
12
obj = {
func() {
const arrowFunc = () => {
console.log(this._name);
};
return arrowFunc;
},
_name: 'obj',
};
obj.func()();
func = obj.func;
func()();
obj.func.bind({ _name: 'newObj' })()();
obj.func.bind()()();
obj.func.bind({ _name: 'bindObj' }).apply({ _name: 'applyObj' })();
- 答案
// func中return函数为箭头函数,this指向其外部函数的this指向
// 'obj' 指向obj
// undefined 指向window
// 'newObj' 指向bind中的函数
// undefined 指向window
// 'bindObj' bind函数的this指向不会被改变 指向bind中的对象
13
function a() {
var a = 12;
var obj = {
a: 1,
b: this.a + 10,
};
console.log(obj.b);
console.log(this.a);
}
a();
- 答案
// fun a 10 this指向window
// fun a this指向window