函数中的this

this的基本使用很简单,直观看上去同其他语言一样,在对象的函数内用“this”来获得对象自身的引用,从而实现对对象自身数据的访问、修改。下面是最简单的使用例子:

1
2
3
4
5
6
7
8
9
10
let user = {
name: "ZZY",
age: 24

hello() {
alert(this.name)
}
}

user.hello()

然而需要注意的是,JavaScript中的”this”是在运行时动态确定的,同一个函数可以分别被不同的对象所使用,从而这个函数中的”this”也将会表示不同对象的引用,就像下面的这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
let user = {name: "ZZY"}
let admin = {name: "LYQ"}

function hello(){
alert(this.name)
}

user.func = hello
admin.func = hello

user.func() // ZZY
admin.func() // LYQ
hello() // undefine

那么js编译器在调用含“this”的函数时,必须需要知道这个this是引用的哪个对象,如果不知道,就会报错,就像下面这样

1
2
3
4
5
6
7
8
9
let user = {
name: "ZZY",
hello() {
alert(this.name)
}

let hello = user.hello
hello() // error!
}

要让this正确引用对象,js编译器使用了一种特殊的类型,叫“引用类型”(Reference Type),这种类型是三个值的组合(base,name,strict):

  • base:对象
  • name:对象的属性
  • strict:is true if use strict is in effect (????)

当调用”user.hello()”时,”.”号返回的不是一个函数,而是一个特殊的“引用类型”,即上面那三个值的组合,这样运行时才能确定this所引用的对象是哪个。而这种引用类型只是编译器内部使用,并不能传递到外部给用户使用,所以执行”let hello = user.hello”之后,hello就是单纯的孤零零的函数,而不是三个值的组合。

箭头函数没有自己的this

箭头函数没有自己的this,如果箭头函数中使用了this,那么这个this将会直接继承自这个箭头函数定义时所在的代码语境中的this,即如下代码所示:

1
2
3
4
5
6
7
8
9
let user = {
name: "ZZY",
hello() {
let arrow = () => alert(this.name)
arrow()
}
}

user.hello() // ZZY