JavaScript this、回调函数、事件流
this
this 环境对象。
谁调用,this指向谁。
1.普通调用函数
function fn(){
console.log(this)
}
这里的this指向全局对象,打印到控制台是一个window,严格模式下this指向undefined
2.对象方法里面的this
对象 -- { } 里面主要有两个,一个是属性 key:value 一个是方法 方法:函数()
let duixiang = {
name:'www',
get:function(){
console.log(this.name)
}
}
duixiang.get打印到控制台的是www,也就是对象里面的name属性。这时候的this指向的是对象duixiang
3.当函数作为参数被调用的时候
主要是事件监听的处理函数
假设有一个按钮对象button,我们对button进行监听:button.addEventListener(事件,对应函数)
button.addEventListener('click',function(){
console.log(this)
})
打印到控制台的是button对象,我们可以使用this.checked来代替button.checked。这里虽然使用的是匿名函数,但是又名函数的this也同样是button
4.设置this的指向
就是在某个过程中this并不指向我们上面所说的三种情况,而是指向我们自己设置的指向
三个方法:call apply bind
1.call 格式 函数.call(this指向的对象,函数的参数列表) //函数没有参数就可以省略掉参数列表
运用示例
function show(text){//定义函数
console.log(`oh my god ${this.name},${text}`)//函数体输出this的name
}
let student={///对象,里面包含name和id
name:"lili",
id:159847
}
show.call(student,'woaini')//指明this的指向,传递函数的参数
最后在控制台输出oh my god lili,woaini
2.apply,它的传参方式是以数组或者类数组进行传递,然后一一对应到函数的形参列表
格式:函数.apply(this指向,[参数们,参数们])
运用示例
function show(text,num){//定义函数
console.log(`oh my god ${this.name},${text},${num}`)//函数体输出this的name和参数text,num
}
let student={///对象,里面包含name和id
name:"lili",
id:159847
}
show.apply(student,['woaini',123])//指明this的指向,传递函数的参数
其实区别与call不大,主要是传参部分有区别,参数以数组类数组形式传递,形参列表不变,按照先后顺序进行接收
3.bind,这个方法区别于前两个,它不会直接执行函数,而是返回一个新的函数。函数绑定的this会永久绑定。
function show(text,num){//定义函数
console.log(`oh my god ${this.name},${text},${num}`)//函数体输出this的name和参数text,num
}
let student={///对象,里面包含name和id
name:"lili",
id:159847
}
const great = show.bind(student,'i love you','1314')//传参绑定函数,指定this
great()//调用函数
这个方法会绑定this,并且把这个函数返回。我们用变量接收它,然后通过变量可以调用
回调函数
回调函数是个概念,大致意思就是假设有a,b两个函数,在b里面调用a,a就被称为回调函数,再具体的就等以后慢慢扩展。
事件流
事件流是指处理dom事件时事件传播的顺序,主要分为捕获和冒泡。
捕获:从最外层的元素逐渐向目标元素传递
冒泡:从目标元素逐渐向最外层元素传递
捕获
具体流程如上图所示。
捕获的语法格式:button.addEventListener(事件,对应函数,true)在监听事件后添加参数true即可。
捕获会从最上层元素依次执行同名事件到目标元素
同名事件是指必须都是相同的事件才会触发,如果一个单击一个双击就不会触发
冒泡
冒泡是从目标元素到最上层元素的冒泡。它的语法格式就是事件监听button.addEventListener(事件,对应函数)因为第三个参数是默认的false,也就是冒泡。
阻止冒泡(捕获)
在有些情况下,父元素和子元素都会设置上相同的事件监听。它又是默认冒泡的,也就是说我们触发子元素就一定会触发父元素。这就会导致程序出现问题。所以我们就要阻止默认的冒泡。
语法格式:事件对象.stopPropagation() //事件对象--》 event。监听处理函数的默认参数事件对象。
这个不仅仅会阻止冒泡也会阻止捕获
设置了这个之后就不会发生触发一个子元素事件,父元素的同名事件也跟着一起触发了
示例
<body>
<div id="div1">
<div id="div2">
<div id="div3">
</div>
</div>
</div>
<script>
const div1 = document.getElementById('div1');
const div2 = document.getElementById('div2');
const div3 = document.getElementById('div3');
div1.addEventListener('click', function (event) {
alert('i an div1')
})
div2.addEventListener('click', function (event) {
alert('i an div2')
})
div3.addEventListener('click', function (event) {
event.stopPropagation();
alert('i an div3')
})
</script>
</body>
我们点击div3的时候只会提示一个 i an div3,因为我们使用了event.stopPropagation()阻止冒泡或者捕获