2,箭頭函數 function(){} --- ()=>{} 箭頭函數 function(e){} --- e =>{} 箭頭函數 function(){一行} --- ()=>一行 箭頭函數 function(e){一行} --- e =>一行 箭頭函數 特點:1,this指向與一般的function函數不同 聲明式 function fun(){} this指向,window 賦值式 var fun = function(){} this指向,window forEach()循環 this指向,window 定時器,延時器 setInterval(function(){} , 時間) this指向,window 對象中的函數 const obj = {fun:function(){}} this指向,obj對象 事件處理函數 標簽.addEventListener(事件類型,function(){}) this指向,標簽對象 箭頭函數的this指向,是父級程序的this指向 如果父級程序有this指向,指向向的就是父級程序的this指向 如果父級程序沒有this指向(對象,數組是沒有this),指向的是window 2,箭頭函數,無法改變this指向 3,改變this指向 函數.call(參數1,其他參數...) 立即執行函數,並且改變函數的this指向為參數1表示的內容 其他參數,是原始函數的實參,多個實參使用逗號間隔 函數.apply(參數1,[數組參數]) 立即執行函數,並且改變函數的this指向為參數1表示的內容 數組參數,是原始函數的參數,多個參數以數組的單元的形式存儲 函數.bind(參數1) 不會立即執行函數,而是生成一個新的函數 新函數,參數,程序內容,都與原始函數相同 只是this改變為參數1表示的內容
一.箭頭函數
所謂的箭頭函數 是函數的另一種語法形式 const fun = function(){} 普通函數 const fun = ()=>{} 箭頭函數 將匿名函數的部分,從 function(){} 寫成 ()=>{} 的形式 如果函數只有一個參數,可以不寫() const fun = function(e){} 普通函數 const fun = e => {} 箭頭函數 如果執行體中只有一行代碼,可以不寫{} const fun = e=>{console.log(e)} 普通箭頭函數 const fun = e=> console.log(e) 不寫{}箭頭函數 const oDiv = document.querySelector('div'); // 普通函數 oDiv.addEventListener('click' , function(){ console.log('我是div標簽') }) // 箭頭函數 oDiv.addEventListener('click' , ()=>{ console.log('我是div標簽'); }) // 只有一個參數,可以不寫(),直接定義一個參數 oDiv.addEventListener('click' , e=>{ console.log(e); }) // 只有一行代碼,不寫{} oDiv.addEventListener('click' , e=>console.log(e) )
二.箭頭函數的this指向
箭頭函數中的this指向 為什么要有箭頭函數? 是為了配合明天要講的面向對象和構造函數 在箭頭函數中,this指向有特殊的意義,專門可以用來配合構造函數和面向對象編程思想 在箭頭函數中,this指向,父級程序的this指向 如果父級程序有this指向,那么箭頭函數指向的就是父級程序的this 如果父級程序沒有this指向,那么指向的就是window 關於this的總結 1,普通的function函數 聲明式 --- window 賦值式 --- window forEach循環 --- window 定時器,延時器 --- window 對象中的函數 --- 對象本身 事件綁定事件處理函數 --- 綁定事件的標簽 2,箭頭函數的this指向 父級程序的this指向 如果父級程序有this指向(父級程序也是函數),this指向的就是父級程序的this指向 如果父級程序沒有this指向(數組,對象....),this指向的是window 復習this指向 ***************普通函數的this指向************** 聲明式,賦值式/匿名函數,對象中函數,綁定的事件處理函數 this都是指向的調用函數時,之前定義的內容 1,聲明式 --- 指向的是window function fun1(){ console.log(this); } fun1(); 2,匿名函數/賦值式 --- 指向的是window const fun2 = function(){ console.log(this); } fun2(); 3,定義在對象中的函數 --- 指向的是對象 const obj = { fun3 : function(){ console.log(this); } } obj.fun3(); 4,綁定的事件處理函數 --- 指向的是綁定事件處理函數的標簽 const oDiv = document.querySelector('div'); // oDiv.onclick = function(){ // console.log(this); // } oDiv.addEventListener('click' , function(){ console.log(this); }) *******************箭頭函數的this指向******************** 與普通函數的this指向是有區別的 箭頭函數中,this的指向是父級程序的this指向 當前的程序,箭頭函數的父級程序, 如果沒有,則this指向的就是window oDiv.addEventListener('click' , ()=>{ console.log(this); }) // 對li進行操作 const oLis = document.querySelectorAll('li'); oLis.forEach(function(item,key){ // console.log(this); // 輸出的是forEach的函數的this指向 // 箭頭函數的this,是父級程序,forEach()的this,是window item.addEventListener('click' , ()=>{ // console.log(key,this); }) }) forEach()中 函數的this指向,就是window const arr = [1,2,3,4,5,6]; arr.forEach(function(){ console.log(this); }) const obj = { // 普通函數,this指向對象 fun1 : function(){console.log(this)}, // 箭頭函數this指向是,父級程序 // 父級程序是對象 // 只有函數有this,obj對象沒有this // 父級程序沒有this,指向的是window fun2 : ()=>{console.log(this)}, // fun3是一個普通函數,this指向的是obj對象 fun3 : function(){ // fun4,是一個箭頭函數,this指向的是父級程序的this指向 // 父級程序是fun3,fun3的this是對象,fun4箭頭函數的this也是對象 const fun4 = ()=>{console.log(this)}; fun4(); } } obj.fun1(); obj.fun2(); obj.fun3();
三.改變this指向
重點:箭頭函數,不能改變this指向,只有普通function函數,能改變this指向 改變this指向的方法 1, call()方法 語法: 函數.call(參數1,其他參數....可以是多個或者沒有 ) 作用: 調用並且執行函數,同時,將函數的this指向,定義為指定的內容(參數1) 參數1,是改變的this的指向 其他參數,是原始函數的實參,原始函數有幾個形參,此時就要對應的輸入幾個實參,沒有形參,就沒有實參 2, apply()方法 語法: 函數.apply(參數1,參數2) 只有兩個參數 參數1:改變的this的指向內容 參數2:原始函數的實參,必須是一個數組的形式,將實參定義成數組的單元 其他用法和作用於 .call是相同的 總結: call方法與apply方法,作用,效果,都是完全一致的 只是對於原始函數的參數賦值方法,不同 call方法是通過其他多個參數來實現 apply方法是通過一個數組參數,來實現 兩個方法沒有本質的區別,愛用哪個用那個 3, bind()方法 語法: const 變量 = 函數.bind(參數1); 不是立即執行函數(下一篇博客有介紹 立即執行函數) 生成一個新的函數,這個新的函數是改變this指向之后的新的函數 參數1,定義的要改變的的this指向 其他參數,一般不定義,是使用函數原有的形參 總結: call apply 都是立即執行函數 參數1,都是改變的this指向 其他參數,是原始函數的形參(可以有,也可以沒有) bind 不是立即執行函數,是生成一個新的函數 參數1,是改變的this指向 就使用原始函數的形參 const obj1 = { name:'張三', age:18, sex:'男', } const obj2 = { name:'李四', fun2 : function(){ console.log(this); } } // 對象中的函數,this指向的是這個對象,obj2 obj2.fun2(); // 改變this指向,指向的是obj1這個對象 // 代用,並且執行fun2這個函數,同時將fun2的this指向,從原始的obj2,改變為obj1 obj2.fun2.call(obj1); // 帶有參數的函數,this指向的改變 // 定義的帶有參數的普通函數 function fun3(name,age,sex){ console.log(name,age,sex,this); } // 執行時,輸出實參,此時this指向是window fun3('張三',18,'男'); // 改變this指向 , call方法 fun3.call(obj1,'李四',20,'女'); // 改變this指向 , apply方法 fun3.apply(obj1 , [ '王五' , 20 , '不知道' ]) // bind方法,不是立即執行函數,而是定義生成一個新的函數 // 新生成的函數,this指向是參數1 // 新生成的函數,形參是原始函數fun3的形參 const fun4 = fun3.bind(obj1); fun4('王二麻子' , 100 , '不詳');
四.注意事項特別說明
面向對象和面向過程 從面向過程,改造成面向對象 1,獲取的數據,標簽對象,要以參數的形式,定義給構造函數和實例化對象 獲取標簽對象時,一般獲取父級,傳參父級,在構造函數中,通過父級標簽,獲取子級標簽獨享 2,必須非常非常非常注意 this的指向,一般在面向對象中 都是使用箭頭函數 如果萬一不能清楚地知道this指向,可以先輸出 this 3,其他步驟和思路基本相同,沒有區別 總結: 1,改不改箭頭函數,看內部是否需要 指向實例化對象的this 如果需要,可以改箭頭函數,或者是提前存儲this指向 如果不許需要,改不改箭頭函數都行 一切以實現程序為最終需求,程序能執行就可以 2,之前面向過程的是參數,數據等, 現在是面向對象編程,要在對象的屬性中,定義參數數據 也就是通過 構造函數 this.屬性 = 屬性值 語法來定義需要獲取的參數數據 3,定義在構造函數方法中的一些變量數據,並不是定義在實例化對象中的屬性 沒有必須寫成 this.屬性 = 屬性值 的形式 只要寫成普通的變量定義即可 使用時,也是直接使用變量,不需要添加this 4,在構造函數的方法中,調用其他的函數方法 語法形式 應該是 實例化對象.函數方法名稱() 在構造函數中,使用this來指向實例化對象,寫成 this.函數方法名稱()
轉載: https://blog.csdn.net/DcTbnk/article/details/105419682
