this的指向
this的指向和函数在哪里定义无关,和如何调用有关
以下foo函数调用方式不同,this的值也不同
function foo(){
console.log(this)
}
foo()
var obj = {
foo: foo
}
obj.foo()
obj.foo.apply("hello")
执行结果如下图所示
this四种绑定方式
一、默认绑定
var fn2 = obj2.bar
fn2()
// 4、函数嵌套调用
function foo1() {
console.log('foo1', this)
}
function foo2() {
console.log('foo2', this)
foo1()
}
function foo3() {
console.log('foo3', this)
foo2()
}
foo3()
// 5、通过闭包调用
var obj2 = {
bar: function () {
return function () {
console.log(this)
}
}
}
obj2.bar()()
执行结果如下
以上五种调用方式全都属于默认绑定,因为他们最终都是单独的对函数进行调用
二、隐式绑定
调用的对象内部有对函数的引用
function foo() {
console.log(this)
}
var obj1 = {
name: 'obj1',
foo: foo
}
obj1.foo()
var obj2 = {
name: 'obj2',
bar: function () {
console.log(this)
}
}
obj2.bar()
var obj3 = {
name: 'obj3',
baz: obj2.bar
}
obj3.baz()
以上代码执行结果为
以上三种都属于隐式绑定,他们都是通过对象调用,this就指向了该对象
三、显式绑定
不希望在对象内部包含这个函数的引用,但又希望通过对象强制调用,使用call/apply/bind进行显式绑定
function foo() {
console.log(this)
}
var obj = {
name: 'obj1',
}
foo.call(obj)
foo.apply(obj)
foo.call("xxx")
以上代码的执行结果为
foo函数直接调用this应该指向window,这里通过call/apply来改变了this的指向
四、new绑定
通过new关键字来创建构造函数的实例,绑定this
function Person(name, age) {
this.name = name
this.age = age
}
const p1 = new Person('alice', 20)
const p2 = new Person('mogan', 24)
console.log(p1)
console.log(p2)
以上代码的执行结果如下
此时this指向的是通过new创建的实例对象