在浏览器中有一个神奇的关键字
this
代指某样东西
谁调用它, 它就会指向谁
全局
如果在控制台中输入this
会打印出Window
consoel.log(this)
> Window{...}
因为是浏览器调用的this
那么this
就会指向浏览器的全局对象Window
比如这里有一个函数foo
function foo(){
console.log(this)
}
如果执行foo
这个函数那么也会打印出Window
foo()
> Window {...}
因为是浏览器调用的foo
函数
foo
函数里面打印this
而谁调用的它,this
就会指向谁
所以执行流程是这样的
Window
调用 了foo
函数,函数 执行 打印this
是Window
调用的this
所以this
指向的Window
对象中
那么有没有其他情况呢?
比如我定义一个对象obj
里面有一个属性是foo
值是一个函数
var obj={
foo:function foo(){
console.log(this)
}
}
如果我执行如下操作控制台会打印什么?
obj.foo()
> {foo:foo()}
可以看到竟然打印出了obj
对象
因为是obj
调用 的foo
函数 函数在去 执行 打印
谁 调用 的 this
呢?
是obj
谁 调用 的this
那么this
就指向谁
obj
调用 的this
那么this
就会指向obj
问: 下面会打印什么?
var obj={
foo1:function (){
function foo2(){
console.log(this)
}
foo2()
}
}
obj.foo1()
答案是
> Window {...}
首先要分清 调用 和 执行
调用 表示对象调用属性
比如
var a={
name:"狗蛋"
}
a.name
表示 a
对象 调用 属性 name
再比如
function foo(){}
foo()
表示 执行 foo
函数
那么回过头来看问题
var obj={
foo1:function (){
function foo2(){
console.log(this)
}
foo2()
}
}
obj.foo1()
obj
调用 的 foo1
函数
而 foo1
函数里面是 执行 foo2
那么谁调用的 foo2
呢?
没有任何对象调用它
那么 foo2
里的this
指向的就是Window
如果没有任何明确的对象调用 this
那么this
就会指向 Window
关于箭头函数
箭头函数的this
会绑定到上下文的this
比如
var obj={
foo:()=>{console.log(this)}
}
obj.foo()
因为使用的是箭头函数
而箭头函数的this
会指向到外部的this
比如
var obj={
foo1:function (){
(()=>{console.log(this)})()
}
}
obj.foo1()
箭头函数的this
会绑定到外部的this
所以打印的是obj
对象
类
JS
中类里使用this
关键字和上方是一样的
比如:
这里声明一个Goudan
类
class Goudan{
constructor(){
this.name = '狗蛋'
}
}
constructor
代表构造方法
当创建Goudan
对象时会执行一次构造方法
如:
class Goudan{
constructor(){
console.log(11)
}
}
new Goudan()
// 此处会执行构造方法里的打印
> 11
那么回顾上面的类,构造方法里的this
代表什么呢?
如果打印出来this
,会出现这种结果
> Goudan {...}
这是因为在类中的this
会指向当前所在的类
这也是为什么在Vue
中使用data
里的数据需要在属性前面加上this
因为Vue
将data
里的数据挂载到了当前的Vue
对象上
使用时this
也就代表了当前的Vue
对象
案例:
class Goudan{
constructor(){
this.name = '狗蛋';
}
say(){
console.log(this.name);
}
}
let goudan = new Goudan();
goudan.say();
控制台会打印什么?
答案:
> 狗蛋
解析:
在 new Goudan()
时创建一个对象并执行类里的constructor
构造方法
构造方法中的this
指向的是创建出来的对象,里面的name
属性并赋值狗蛋
在这个类里有一个方法say
方法打印this.name
而say
里的this
谁调用它this
就指向谁
而new Goudan
创建出来的对象赋值给了变量goudan
goudan
调用了say
方法this
指向goudan
而在执行构造方法时赋值给了name='狗蛋'
所以打印出狗蛋
注意
在类中并没有一个全局对象Window
所以当this
执行不明确时会出现undefined
比如
class Goudan{
constructor(){
this.name = '狗蛋';
}
say(){
function foo(){
console.log(this);
}
foo();
}
}
let goudan = new Goudan();
goudan.say();
// 打印出
> undefined
因为没有任何对象调用foo()
所以this
指向不明确
那么this
就是undefined
在类中也是适用箭头函数的
例如:
class Goudan{
constructor(){
this.name = '狗蛋'
}
say(){
(_=>{ // 这里箭头函数绑定了上下文 所以this就是指向创建出来的对象
console.log(this.name);
})();
}
}
let goudan = new Goudan();
goudan.say();
// 控制台打印
> 狗蛋