下面这段代码输出多少呢?是1还是2?
function foo() {
console.log(value);
}
var value = 1;
function bar() {
var value = 2;
foo();
}
bar();
答案是1,因为这里foo()函数是独立调用的,不是作为对象的方法调用,this默认指向window。
this默认指向window
// 函数独立调用
// 1、直接调用
function foo() {
console.log(this);
}
foo();
// 2、对象中的函数
var obj1 = {
foo: foo,
};
var fn1 = obj1.foo;
fn1();
// 3、函数嵌套调用
function foo1() {
console.log("foo1", this);
}
function foo2() {
console.log("foo2", this);
foo1();
}
function foo3() {
console.log("foo3", this);
foo2();
}
foo3();
// 4、通过闭包调用
var obj2 = {
bar: function () {
return function () {
console.log('闭包',this);
};
},
};
obj2.bar()();
执行结果如下:
this指向调用函数的对象
当函数作为对象中的方法时,指向调用该函数的对象
// this指向调用函数的对象
function foo() {
console.log(this);
}
var obj1 = {
name: "obj1",
foo: foo,
};
obj1.foo();
var obj2 = {
name: "obj2",
bar: function () {
console.log(this);
},
};
obj2.bar();
var obj3 = {
name: "obj3",
baz: obj2.bar
};
obj3.baz();
call/apply/bind改变this指向
注意:使用call/apply/bind不会改变箭头函数中this的指向
function foo() {
console.log(this);
}
var obj = {
name: "obj1",
};
foo.call(obj);
foo.apply(obj);
构造函数中的this
new关键字会将构造函数中的this指向实例化对象
function Person(name, age) {
this.name = name;
this.age = age;
console.log('new',this);
}
const p1 = new Person("alice", 20);
const p2 = new Person("mogan", 24);
console.log(p1);
console.log(p2);
箭头函数中的this
var name = 'demo';
var obj = {
name: 'obj',
fn: ()=>{
console.log(this.name);
}
}
obj.fn(); //demo
箭头函数中没有自己的this,所以向上层作用域查找,找到全局作用域(定义对象obj时是不产生作用域的),所以this.name = window.name,即demo。