blog
blog copied to clipboard
JavaScript中的this关键词
JavaScript拥有一个名为this 的关键字,在JavaScript程序中的不同位置,this所引用的值会有所不同。
这其实是一件比较头疼的事,因为随着ES6的发布和NodeJS的搅和,这个概念可能会被混淆。
今天我们只说浏览器中的this。
全局上下文中
这个还是比较好理解的,如果直接在代码中使用this,那么this === window。 所以下面两行赋值做的是同一件事,创建一个名为hello的全局变量。
console.log(this === window); // true
this.hello = 'hello world';
window.hello = 'hello world';
console.log(this.hello); // hello world
console.log(window.hello); // hello world
console.log(hello); // hello world
函数上下文中
在函数或是闭包中引用了this结果又会如何?
在这个没有任何嵌套的函数中,this的指向取决于你是否使用了严格模式。
简单的例子
function hello () {
console.log(this === window); // true
console.log(this); // object global
}
hello();
function hello () {
"use strict";
console.log(this === window); // false
console.log(this); // undefined
}
hello();
在模块模式中
下面来看一下,在这种情况中,this的指向又发生了什么变化。
var hello = {
init: function () {
console.log(this); // references hello
},
};
hello.init();
所以你可以向下面这样做,来封装一个模块。
var hello = {
default: {
base: 'www.baidu.com',
limit: 20,
},
init: function (cfg) {
var config = cfg || this.default;
console.log(config);
},
};
hello.init();
嵌套函数
在匿名函数中
var hello = {
init: function () {
setTimeout(function () {
console.log(this); // window
})
},
};
hello.init();
ES6箭头函数中
在ES6箭头函数中,this和普通函数中的指向是不同的,他永远会跟随上下文。
所以我们不会在非严格模式下的匿名函数或者全局函数中遇到this指向window的情况了。
const hello = {
init: function() {
console.log(this === hello); // true
setTimeout(() => {
console.log(this === hello); // true
})
},
};
hello.init();
再复杂一点
const hello = {
init: function() {
'use strict';
console.log(this === hello); // true
const func = function () {
console.log(this === undefined); // true
setTimeout(() => {
console.log(this === undefined); // true
})
}
setTimeout(() => {
console.log(this === hello); // true
})
setTimeout(function() {
console.log(this === window); // true
})
func();
},
};
hello.init();