通过学习,this使用有如下情况:
一、直接调用其中有this的函数
function foo(){
var a = 1 ;
console.log(this.a); // 10
}
var a = 10;
foo();
直接调用函数,这个函数中的this代表全局对象window.
二、一个对象调用有this的函数
function foo(){
console.log(this.a);
}
var obj = {
a : 10,
foo : foo
}
foo(); // undefined
obj.foo(); // 10
一个对象调用这个函数,这个函数中的this代表调用者,也就是上例中的obj。如果是链性的关系,比如 xx.yy.obj.foo();, 上下文取函数的直接上级,即紧挨着的那个,或者说对象链的最后一个。
三、单独使用 this
单独使用 this,它指向全局对象 window:
var x = this;
console.log(x); //window
三、call apply bind这些方法可以显式地设置函数执行时的 this 值。
function foo(xx){
console.log(this.a + xx);
}
var obj = {
a : 10 //去掉里面的foo
}
foo.call(obj,10); // 20
call 方法接受多个参数,第一个参数指定 this 的值,后续参数是传给函数的参数。也就是说上例中foo函数中的this代表(指向)obj。
apply方法接受多个参数,第一个参数指定 this 的值,第二个参数必须是数组,这个数组代表传给函数的参数列表,除了是数组其它功能与call类似。
function foo(){
console.log(this.a);
}
var obj = { a : 10 };
foo = foo.bind(obj);
foo(); // 10
bind只有一个参数,且不会立刻执行,将this指向(绑定)这个参数,并将绑定好的函数返回。
四、new
function Person(name) {
this.name = name;
}
const person = new Person('Bob');
console.log(person.name); // 输出 'Bob'
当使用 new 关键字调用构造函数时,this 指向新创建的实例对象。注意函数名与new对象名相同。
特别注意 : 如果原函数返回一个对象类型,那么将无法返回新对象,你将丢失绑定this的新对象,例:
function foo(){
this.a = 10;
return new String("捣蛋鬼");
}
var obj = new foo();
console.log(obj.a); // undefined
console.log(obj); // "捣蛋鬼"
五、箭头函数的this
箭头函数不会创建自己的 this,它会捕获其所在的上下文的 this 值。箭头函数的this绑定无法被修改。
var people = {
Name: "海洋饼干",
getName : function(){
return ()=>{
console.log(this.Name);
}
}
};
var bar = people.getName(); //获得一个永远指向people的函数,不用想this了,岂不是美滋滋?
bar(); // 海洋饼干
再看一段代码:
var obj= {
that : this,
bar : function(){
return ()=>{
console.log(this);
}
},
baz : ()=>{
console.log(this);
}
}
console.log(obj.that); // window
obj.bar()(); // obj
obj.baz(); // window
- 我们先要搞清楚一点,obj的当前作用域是window,如 obj.that === window。
- 如果不用function(function有自己的函数作用域)将其包裹起来,那么默认绑定的父级作用域就是window。
- 用function包裹的目的就是将箭头函数绑定到当前的对象上。函数的作用域是当前这个对象,然后箭头函数会自动绑定函数所在作用域的this,即obj。
志远总结: