1.普通函数直接调用
var a = 1 function test(){ console.log(this.a) } test() //1 //因为test是直接调用的,没有其他的绑定规则,这里进行了默认绑定,将全局对象绑定this上, //所以this.a 就解析成了全局变量中的a2.内置函数
function f(){ console.log(this) } setTimeout(f,1000) //window3 .回调函数
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,故打印bb5.改变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