1.不使用箭头函数时
let Lesson = {
site: '后盾人',
lists:['js','css','mysql'],
show: function (param) {
console.log(this);
// {site: '后盾人', lists: Array(3), show: ƒ}
return this.lists.map(function(title){
console.log(this);
// Window {window: Window, self: Window, document: document, name: '', location: Location, …}
})
}
}
Lesson.show()
第一个console:直接挂载到对象属性上的函数,this指向所属对象
第二个console:未直接挂载到对象属性上的函数,this指向window
2.使用箭头函数
// 2.使用this
{
let Lesson = {
site: '后盾人',
lists:['js','css','mysql'],
show: function (param) {
console.log(this);
// {site: '后盾人', lists: Array(3), show: ƒ}
return this.lists.map((title)=>{
console.log(this);
// {site: '后盾人', lists: Array(3), show: ƒ}
})
}
}
Lesson.show()
}
map中改用箭头函数后,this指向了上下文,也就是父级作用域,即这里的Lesson对象。
3.给dom元素添加事件
{
let Dom = {
site: '后盾人',
bind: function() {
const button = document.querySelector('button')
button.addEventListener("click",function(){
console.log(this)
})
button.onclick = function(){
console.log(this)
}
/**
* 这两种写法的效果是一样的,this都指向button对象
* 可以理解为onclick这个函数挂载到button对象上的一个属性
* 上文提到,直接挂载到对象属性上的函数,this指向所属对象
*/
}
}
Dom.bind()
}
两处this均指向button对象
// 改成箭头函数后
{
let Dom = {
site: '后盾人',
bind: function() {
const button = document.querySelector('button')
button.addEventListener("click",()=>{
console.log(this)
})
}
}
Dom.bind()
}
改成箭头函数后,this指向父级作用域中的this,即bind函数中的this,而bind函数是挂载到Dom对象上的,因此this指向Dom
4.思考:上面代码中,既要用到button对象,又要用到Dom对象怎么办?
1.使用evenet参数
// 使用event参数
{
let Dom = {
site: '后盾人',
bind: function() {
const button = document.querySelector('button')
button.addEventListener("click",event=>{
console.log(this)
console.log(event.target)
})
}
}
Dom.bind()
}
此时,this指向Dom对象,event.target指向button对象
3.另外定义一个变量记录Dom作用域的this
// 6 定义self
{
let Dom = {
site: '后盾人',
bind: function() {
const self = this
const button = document.querySelector('button')
button.addEventListener("click",function(){
console.log(this)
console.log(self)
})
}
}
Dom.bind()
}
此时也能同时拿到Dom对象和button对象
4.使用handleEvent
// 使用handleEvent
{
let Dom = {
site: '后盾人',
handleEvent: function (event) {
console.log(event.target)
console.log(this)
},
bind: function() {
const button = document.querySelector('button')
// 事件会自动在传入对象中寻找handleEvent方法
button.addEventListener("click",this)
}
}
Dom.bind()
}
5.思考:上面代码中,场景变成两个button,既要用到点击的button对象,又要用到Dom对象怎么办?
{
let Dom = {
site: '后盾人',
bind: function() {
// 此时会拿到两个button
let buttons = document.querySelectorAll('button')
buttons.forEach(function(elem) {
elem.addEventListener('click',function() {
// 此时this指向各自点击的button对象
console.log(this)
})
})
}
}
Dom.bind()
}
使用箭头函数后
// 两个button时
{
let Dom = {
site: '后盾人',
bind: function() {
// 此时会拿到两个button
let buttons = document.querySelectorAll('button')
buttons.forEach((elem) =>{
console.log(this)//指向Dom对象
elem.addEventListener('click',()=> {
// 此时this指向各自点击的button对象
console.log(this)//指向Dom对象
})
})
}
}
Dom.bind()
}
此时this指向了Dom
再加上event参数
{
let Dom = {
site: '后盾人',
bind: function() {
// 此时会拿到两个button
let buttons = document.querySelectorAll('button')
buttons.forEach((elem) =>{
console.log(this)//指向Dom对象
elem.addEventListener('click',(event)=> {
// 此时this指向各自点击的button对象
console.log(this)//指向Dom对象
console.log(event.target)//指向点击的button对象
})
})
}
}
Dom.bind()
}