1.全局执行上下文中的this
function foo() {
console.log(this)//指向window
}
foo()
这段代码是在全局环境下执行的,所以this指向window
2.通过函数的call方法设置
let bar = {
myname: "x",
age: 18
}
function foo() {
this.myname = 'y'
}
foo.call(bar)
console.log(bar) //myname:"y"
console.log(myname) //es6.html:22 Uncaught ReferenceError: myname is not defined
call方法使得foo函数中的this不在指向window,而是指向了bar对象,所以最后会报错。除了call,你还可以使用bind和apply来改变this指向。
3.通过对象调用方法中的this
let bar = {
myname: "x",
age: 18,
show: function() {
console.log(this) // bar{}
}
}
bar.show()
使用对象来调用其内部的一个方法,该方法的this指向对象本身。
下面我们修改一下这段代码:
let bar = {
myname: "x",
age: 18,
show: function() {
console.log(this)
}
}
var foo = bar.show
foo() //window
执行这段代码,你会发现this又指向全局的window对象了。
小结:在全局环境中调用一个函数,函数内部this指向的是全局对象window;通过一个对象来调用其内部的一个方法,该方法中的this指向对象本身。
4.构造函数中的this
function CreateObj() {
this.name = 'x'
}
var myobj = new CreateObj() // this指向myobj这个对象
5.箭头函数
btn.onclick = function() {
console.log(this) //btn
}
btn.onclick = () => {
console.log(this) //指向window
}
- 函数体内的this对象,就是定义时所在的对象,不是使用时所在的对象。固定改变不了
- 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
注意
1.嵌套函数中的this不会从外层函数中继承
var obj = {
show: function() {
function bar() {
console.log(this)
}
bar() // window
}
}
obj.show()
2.定时器内部的this
注意看下面这两张图片中的代码:
setTimeout实际为window.setTimeout,所以左图this指向window。而右图使用了箭头函数,this指向函数定义时所在的对象
3.事件中的this
addEventListener()事件处理程序会在其所属元素的作用域内运行,但当用了箭头函数则会导致里面的this指向改变。因此不建议在创建事件的时候搭配箭头函数使用
还需注意:另一种添加事件的方法attachEventIE事件处理程序会在全局作用域中运行,因此this = window。
p2.addEventListener('click', function () {
console.log(this) //p2元素
})
p2.addEventListener('click', event => {
console.log(this) //window
})
当然,实战才是硬道理,各位,可以开始码代码了!!!