this是使用常规方法调用函数时(call
)传递的第一个参数,它能够在函数调用时修改,在函数没有调用的时候,this的值是没法肯定的。javascript
常见写法(简写):java
function test(name) {
console.log(name)
console.log(this)
}
test('Jerry') //调用函数
复制代码
完整写法:函数
function test(name) {
console.log(name)
console.log(this)
}
test.call(undefined, 'Tom')
复制代码
若是你传的context 是 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)ui
默认thisthis
const obj = {
name: 'Jerry',
greet: function() {
console.log(this.name)
}
}
obj.greet() //第一种调用方法(语法糖)
obj.greet.call(obj) //第二种调用方法
复制代码
手动指定thisspa
const obj = {
name: 'Jerry',
greet: function() {
console.log(this.name)
}
}
obj.greet.call({name: 'Spike'}) // Spike
复制代码
构造函数里的this稍微有点特殊,每一个构造函数在new以后都会返回一个对象,这个对象就是this,也就是context上下文。code
function Test() {
this.name = 'Tom'
}
let p = new Test()
console.log(typeof p) // object
console.log(p.name) // Tom
复制代码
new
关键字会建立一个空的对象,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。对象
当this碰到return时继承
function fn() {
this.user = 'Jerry';
return {}; // undefined
return function(){}; // undefined
return 1; // Jerry
return undefined; // Jerry
}
var a = new fn;
console.log(a.user);
复制代码
若是返回值是一个对象,那么this
指向的就是那个返回的对象,若是返回值不是一个对象那么this仍是指向函数的实例。ip
function fn() {
this.user = 'Jerry';
return null;
}
var a = new fn;
console.log(a); // fn {user: "Jerry"}
复制代码
虽然null也是对象,可是在这里this仍是指向那个函数的实例,由于null比较特殊。
window.setTimeout()和window.setInterval()的函数中的this有些特殊,里面的this默认是window对象。
MDN官方文档:箭头函数不会建立本身的this,它只会从本身的做用域链的上一层继承this。
不使用箭头函数
const obj = {
a: function() { console.log(this) }
}
obj.a() // {a: ƒ} obj对象
复制代码
使用箭头函数
const obj = {
a: () => {
console.log(this)
}
}
obj.a() // window
复制代码
例子
const obj = {
a: () => {
console.log(this)
}
}
obj.a.call('123') // window
复制代码
结合window.setTimeout()
const obj = {
a: function() {
console.log(this)
window.setTimeout(() => {
console.log(this)
}, 1000)
}
}
obj.a.call(obj) //第一个this是obj对象,第二个this仍是obj对象
复制代码
例子1
const obj = {
a: function() { console.log(this) },
b: {
c: function() {console.log(this)}
}
}
obj.a() // obj对象, 至关于obj.a.call(obj)
obj.b.c() // obj.b对象, 至关于obj.b.c.call(obj.b)
复制代码
例子2
const obj = {
a: function() { console.log(this) },
b: {
c: () => {console.log(this)}
}
}
obj.a() // obj对象
obj.b.c() // window!!
复制代码
window对象就是它的上一层this,此例中的多层嵌套只是对象嵌套,这时候没有做用域链
的嵌套,实际上对箭头函数来讲,仍是只有本身一级的做用域,和上一层的window做用域
例子3
function fn0() {
return {
fn1: function () {
var obj = {
a: function() { console.log(this) },
b: {
c: () => console.log(this)
}
}
return obj;
}
}
}
fn0().fn1().b.c() // 获得{fn1: f} fn1对象
复制代码
在ES5中,只有全局做用域和函数做用域,并无块级做用域,因此这里箭头函数仍然绑定外层this值,而非根做用域