JavaScript this关键字有一下几种使用情况:
1.全局执行
2.在函数中执行
3.作为对象的方法调用
4.作为一个构造函数调用
5.箭头函数
6.apply、call和bind
<p>#全局执行#</p>
在浏览器中输出Window对象
console.log(this);
// Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage, sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}
在node中输出global
console.log(this);
// global
<p>#在函数中执行#</p>
在普通函数中执行,this指向Window
function foo () {
console.log(this)
}
foo();
// Window
在“严格模式”中 ('use strict'),this并不会指向Window,而是undefined,目的是消除javascropt中一些不严谨的行为
(function(){
'use strict';
console.log(this);
})();
<p>#作为对象的方法调用#</p>
一个函数作为一个对象的方法调用时,this指向该对象
var obj = {
name: 'zane',
foo: function () {
console.log(this);
}
}
obj.foo();
// Object {name: "zane"}
但是如果把一个变量的方法重新赋值给一个变量,然后直接调用这个变量,this指向Window,因为此时和obj已经没有关系了,和调用一个普通的函数一样
var obj = {
name: 'zane',
foo: function () {
console.log(this);
}
}
var foo2 = obj.foo;
foo2();
// Window
<p>#作为构造调用#</p>
通过new调用构造函数时,this指向构造函数实例化出来的对象,当通过普通方式调用构造函数时(不通过new关键字)this指向Window,和调用普通函数相同
function Person(name) {
this.name = name;
console.log(this);
}
Person.prototype.say = function () {
console.log('Person can say.');
}
var p1 = new Person('someone1');
// Person {name: "someone1"}
var p2 = Person();
// Window
<p>#箭头函数#</p>
箭头函数与普通函数的区别就是this的指向不能更改,this的指向在函数定义时已经确定,其他的与普通函数相同
<p>#apply、call、bind#</p>
他们可以更改函数中的 this 指向
<small>apply:它会立即执行函数,第一个参数是指定执行函数中 this 的上下文,第二个参数是一个数组,是传给执行函数的参数(与 call 的区别)</small>
<small>call:它会立即执行函数,第一个参数是指定执行函数中 this 的上下文,后面的参数是执行函数需要传入的参数;</small>
<small>*bind:它不会执行函数,而是返回一个新的函数,这个新的函数被指定了 this 的上下文,后面的参数是执行函数需要传入的参数;</small>
var obj3 = {
name: 'someone3'
}
function foo3 (name) {
this.name = name;
console.log(this)
}
foo3.call(obj3, 'someone4'); // Object {name: "someone4"}
foo3.apply(obj3, ['someone4']); // Object {name: "someone4"}
var foo4 = foo3.bind(obj3);
var p4 = new foo4('someone4'); // foo3 {name: "someone4"}