一.this指向
1.普通函数直接调用
var a = 1
function test(){
console.log(this.a)
}
test() //1
//因为test是直接调用的,没有其他的绑定规则,这里进行了默认绑定,将全局对象绑定this上,
//所以this.a 就解析成了全局变量中的a
2.内置函数
function f(){
console.log(this)
}
setTimeout(f,1000) //window
3 .回调函数
var a = [1,2].filter(function(item, index){
console.log(this) //window
})
a()
4.对象中
function A(){
this.name = 'aa'
this.action = function(){
console.log(this.name)
}
}
function B(){
this.name = 'bb'
}
B.prototype = new A()
var b = new B()
b.action() //bb
//在b中没找到action的方法,去原型里找,找到之后调用,
//此时调用者是b,因此A中action的方法this指向b,故打印bb
5.改变this指向
var a = 10
function fun(name){
return this.a + '-' + name
}
var obj = {
a: 100,
action: fun
}
console.log(obj.action('oo')) //100-oo
console.log(obj.action.call(window, 'oo')) //10-oo 使用call改变this指向window
console.log(obj.action.apply(this, ['oo'])) //10-oo 使用apply去改变
6.bind() 绑定this指向
var a = 10
function fun(name){
return this.a + '-' + name
}
var obj1 = {
a: 1111,
action: fun
}
var obj2 = {
a: 2222,
action: fun
}
var a1 = fun.bind(obj1)
console.log(a1('999')) //1111-999
console.log(a1.call(obj2, '888')) ////1111-888 绑定之后就无法改变了
二.事件委托、冒泡
1.先看一下下述代码,区分一下target与currentTarget的区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.fatherBox{
width: 100%;
height: 300px;
border: 1px solid red;
padding-top: 50px;
}
.childBox{
width: 50%;
height: 150px;
margin: 0 auto;
border: 1px solid black;
}
</style>
<script>
window.onload = function(){
document.querySelector(".fatherBox").onclick = function(e){
//触发在哪就改变谁
//e.target.style.color = 'red'
//绑定在谁的身上则会触发谁
//e.currentTarget.style.color = 'red'
//this:绑定
this.style.color = 'red'
}
}
</script>
</head>
<body>
<div class="fatherBox">
我是爸爸
<div class="childBox">
我是儿子
</div>
</div>
</body>
</html>
以上例子存在一个小问题,就是color会被继承,因此点击父组件看不出什么问题,尝试三种的时候都需要点击子组件区域
同时,上述例子存在了事件冒泡的过程,点击子组件,触发了父组件的绑定事件,这就是一种事件冒泡
事件冒泡是由微软提出的,事件捕获是由网景提出的,两个方法的流程恰好相反,冒泡是由里而外的,在最里层触发,然后逐级向外传递,直至document对象,而事件捕获则是由最外层触发,然后里面逐级捕获到事件
原生阻止事件冒泡: e.stopPropagation();
2.事件委托
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
<script>
window.onload = function(){
//把点击事件绑定在父元素上
var ul = document.querySelector(".ul")
ul.onclick = function(e){
if(e.target.nodeName == 'LI'){
console.log(e.target.innerHTML)
}
}
}
</script>
</head>
<body>
<div>
<ul class="ul">
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</div>
</body>
</html>
可以看到,对于li的点击事件有两种方式:
1.遍历所有的li,给每一个li都绑定一个点击事件
2.把点击事件绑定在父组件上,然后利用冒泡事件触发父组件的绑定事件,然后通过target得到触发事件的实际对象,再进行相应的操作即可,这就是事件委托的一个简单demo