一、在js代码中this在不同位置会不同,很多时候和自己想要的指向不一样,此时我们首先要确定此时的this的指向是什么并且如何改变this
二、不同环境下的this
2.1、全局下面的this
- 浏览器全局的this
<script type="text/javascript">
console.log(this);
</script>
Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
- node下的this
console.log(this);
{}
2.2、函数中的this
- 普通函数中的this
<script type="text/javascript">
var name='hi';
function This(){
console.log(this);
var name='hello';
console.log(this.name);
}
This();
</script>
window 打印是hi
一个普通函数直接调用的时候,属于全局调用,这时候它的this是window全局的this
- 严格模式下 “use strict”;
"use strict";
function test() {
console.log(this);
};
test();//undefined
//当然,把它放在一个立即执行函数中会更好,避免了污染全局
(function(){
"use strict";
console.log(this);
})();
Undefined
如果在严格模式的情况下执行纯粹的函数调用,那么这里的的 this
并不会指向全局,而是 undefined
,这样的做法是为了消除 js 中一些不严谨的行为:
2.3、对象中的this
- 当一个函数在对象的时候,用对象调用的时候此时this是这个对象
<script type="text/javascript">
//1、
name='hello';
var obj={
name:'hi',
foo:function(){
console.log(this.name);
}
}
obj.foo();
//2、
function hil(){
console.log(this.name);
}
name='hello';
var obj={
name:'hi',
foo:hil
}
obj.foo();
</script>
hi
只要函数在对象中并且对象调用这个函数此时的this都是该对象
注意:如果把对象的方法赋值给一个变量,然后直接调用这个变量就不一样了
<script type="text/javascript">
function hil(){
console.log(this.name);
}
name='hello';
var obj={
name:'hi',
foo:hil
}
var fo=obj.foo;
fo();//被当作普通函数来调用
hello
2.4、构造函数的this
function Person(name) {
this.name = name;
console.log(this); //Person {name: "Abby"}
}
var person = new Person('Abby');
console.log(person.name); //Abby
//2\
function Person(name) {
this.name = name;
console.log(this); //window
}
Person('Jane');
console.log(window.name); //Jane
如果不加 new,表示即作为普通函数调用,指向 window
2.5、定时器的this:超时调用的代码都是在全局执行域中执行的,this 默认指向 window 对象,除非手动改变 this 的指向。
<script type="text/javascript">
function test(){
console.log(this+'=');
}
setTimeout(function(){
console.log(this);
},1000);
setTimeout(test,1000);
</script>
setTimeout 中的回调函数在严格模式下也指向 window 而不是 undefined (是个坑)
在这里如果想改变 this,可是使用 apply/call/bind 等,也可以使用 that 保存 this.
2.5、箭头函数
- 箭头函数里面 this 始终指向外部对象,因为箭头函数没有 this,因此它自身不能进行new实例化,同时也不能使用 call, apply, bind 等方法来改变 this 的指向。
var obj = {
foo() {
console.log(this);
},
bar: () => {
console.log(this);
}
}
obj.foo() // {foo: ƒ, bar: ƒ}
obj.bar() // window