/*===可有可無的開頭start===*/
最近由於一些事兒辭了剛剛找到的工做,處在待業狀態,去稍微的面了幾家公司,有大有小,有好有壞,發現你們問起來的一些ES6的問題跟我想的不同,下來再去研究發現我說的仍是有些缺陷,雖然意思是對的,可是表達的很奇怪,怪不得面試官會誤會,參考了下以前公司大哥的一些和網上大神的,這裏撿着關於箭頭函數和let、const去說一些淺陋的總結(都是爛大街的啦~)
/*===可有可無的開頭end===*/前端
文中大部分偏建議,結合了網上的一些規範整理出來的,也包括了一些特殊的數組和對象的處理。後期你們一塊兒討論
ES6中兩種方式進行函數的定義:箭頭函數 和 function()面試
箭頭函數的區別1: 沒有本身的this,它的this來自它定義時的環境數組
箭頭函數的區別2: 由於沒有本身的this,因此bind、apply、call也對其不起做用閉包
箭頭函數的區別3: 內部不能使用argumentsapp
因此總結起來就是,只要是須要用到內部的this和arguments的狀況下,就不能使用箭頭函數,這是一個基礎,感受上只要注意這個,這兩個能夠隨便用,下面總結了一下dom
let dom_test = documents.getElementById('test'); // 普通方式(正確) dom_test.addEventListener('click', function(){ // 用到了this指向當前的dom_test的dom對象 console.log('當前點擊的按鈕id是:' + this.id); // '當前點擊的按鈕id是:test' }) // 箭頭函數方式(錯誤) dom_test.addEventListener('click',()=>{ // 當前的this指向了箭頭函數定義位置的this,當前this指向window console.log('當前點擊的按鈕id是:' + this.id); // '當前點擊的按鈕id是:undefined' }) // 箭頭函數方式(修正) dom_test.addEventListener('click',()=>{ // 避免這種this綁定到dom_test的使用場景,直接上變量 console.log('當前點擊的按鈕id是:' + dom_test.id); // '當前點擊的按鈕id是:test' })
// 普通形式(正確) function Student(name, age, className){ this.name = name; this.age = age; this.className = className; } new Student('Yupin Tu', 18, 'female'); // Student {name: "Yupin Tu", age: 18, className: "female"} // 錯誤的箭頭函數 // 這樣定義工廠方法時使用new執行會報 ‘XXX is not a constructor’ 的錯誤 let Student = (name, age, className)=>{ this.name = name; this.age = age; this.className = className; } new Student('Yupin Tu', 18, 'female'); // Uncaught TypeError: Student is not a constructor
// 普通方式(正確) let obj = { msg: 'this is a test', showMsg(){ // 用到了this指向obj console.log(this.msg); } } obj.showMsg(); // 'this is a test' // 箭頭函數(錯誤) let obj = { msg: 'this is a test', showMsg:()=>{ //this指向了window console.log(this.msg); } } obj.showMsg(); // undefined
// 正確的 var getSum = function(){ const arr = [...arguments]; let sum = 0; for(let val of arr){ sum += val } return sum } getSum(1,2,3); //6 // 錯誤的 var getSum = ()=>{ const arr = [...arguments]; // 報錯:arguments is not defined let sum = 0; for(let val of arr){ sum += val } return sum } // 修正 var getSum = (...rest)=>{ const arr = [...rest]; // 報錯:arguments is not defined let sum = 0; for(let val of arr){ sum += val } return sum }
由於箭頭函數沒有this的狀況,因此bind、apply、call對其不起做用,若是一個方法定義出來須要用在這個場景下,那麼不能使用箭頭函數(例如一個函數須要被進行柯里化的操做)函數
只要不涉及到this和arguments,箭頭函數就可使用this
箭頭函數的優點:rest
如下是適用場景code
let arr = [1,2,3] arr.map((val)=>val+1); //[2,3,4]
((msg)=>{console.log(msg)})('this is a test'); //'this is a test'
// 很差的使用 let obj = { msg: 'this is a test', getShowMsgFn(){ let _this = this; function showMsg(){ console.log(this.msg); //這時候this是指向window的,因此返回了undefined console.log(_this.msg); //這時候須要對外部的this引用到閉包內,然而_this沒法釋放,形成內存溢出 } return showMsg; } } obj.getShowMsgFn()(); // undefined 'this is a test' // 好的使用 let obj = { msg: 'this is a test', getShowMsgFn(){ let showMsg = ()=>{ console.log(this.msg); //這時候this是指向外部的this,也就是obj } return showMsg; } } obj.getShowMsgFn()(); // 'this is a test'
let和const指令針對於塊級做用域,基本上能替換掉var的變量聲明
let是用來聲明會變化的變量的,而const是聲明「常量或者是不可變化的變量」
/** * 由於const是塊級做用域 * 因此若是一個變量在這個塊裏邊聲明以後再也不會進行賦值操做,應該使用cons * @TODO 但這裏是否須要所有字母大寫? */ const GMSG = ‘this is basic’; function(isChanged){ const staticMsg = 'this would be never changed'; let realtimeMsg = 'this is a test'; if(isChanged){ realtimeMsg = 'It's changed'; } return GMSG + staticMsg + realtimeMsg; }
let 和 const 聲明的變量不會像 var 聲明同樣提高到做用域的最上邊,因此如下狀況請注意
首先看下沒問題的var:
// 沒問題的var方式,var聲明的test會提高到最上邊 function getStr(name){ if(name){ test = name; } var test; return test; } getStr('ZhangSan'); //'ZhangSan' window.test; // undefined // 以上代碼同等於 function getStr(name){ var test; // 被提高到上邊來啦 if(name){ test = name; } return test; }
看一下出問題的let,由於let不會提高,因此
function getStr(name){ if(name){ // 非嚴格模式下會在window上生成一個test屬性去進行操做 // 嚴格模式直接報錯:test is not defined test = name; } let test; return test; // 此時返回的是當前let出來的test,是個undefined } getStr('ZhangSan'); //undefined window.test; // 非嚴格模式下爲'ZhangSan' ,嚴格模式下是undefined
var用在循環中
let arr = [1,2,3]; for(var i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 3 //-----------------等同於----------------- let arr = [1,2,3]; var i; for(i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 因此這裏可以輸出 3
而let的狀況
let arr = [1,2,3]; for(let i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // undefined (?) // -------------由於它不等同於------------- let arr = [1,2,3]; let i; for(i = 0 ; i < arr.length ; i++){ console.log(i); } // 1 2 3 console.log(i); // 此時 i存在 爲 3 // ---------------而是等同於-------------- let arr = [1,2,3]; let _i; // 一個for循環的內部迭代變量,不能訪問 for(_i = 0 ; _i < arr.length ; _i++){ let i = _i; console.log(i); } // 1 2 3 console.log(i); // 此時 i存在 爲 3
後邊沒了,下邊的是一些人力面的總bao結yuan
/*===可有可無的結尾start===*/
面試是最快的查漏補缺的方式。
然而因爲本身的工做經驗主要在一家軟件公司,而後後來的公司入職時間不長就又辭了,因此最近去互聯網公司受到了人資的盤問,以爲本身除了有點害羞表現還能夠,因此也拿到了幾家的offer,可是也是受盡了互聯網公司人資的歧視(居然反問我以前軟件公司還須要加班麼)
最近去了某互聯網媒體巨頭某狐面試,經歷了史無前例的人力面,在她滿臉看不起個人在軟件公司幹了兩年的工做經驗中,我當心翼翼的回答着她挑釁的問題,自稱互聯網人的她對我以前的公司反覆的羞辱和鄙視,我也是不卑不亢(畢竟我只是去試試感受),在最後問我爲何大四上半年就簽了工做,是否是不敢去互聯網公司試試,仍是說大四下半年在忙着補考。而後我說把手機裏的成績單給她看(哈哈,大學仍是有點小成就的),她居然說我是有備而來,嗯,能夠,大公司咄咄逼人吶
還有一些肉眼可見直插肺腑的地域歧視
這裏也總結一下我被問到的問題
···
我家是河北滄州任丘,特別乾淨,由於考不上公務員才被迫來北京謀生,我以前的軟件公司也很厲害,早就不是用JSP寫前端頁面了,加班是我熱愛我作的工做,咱們大學是正正經經的重本大學,我上學那會兒保定的分不比北京低,我沒有夢想,由於我不是汪峯,你們都是在這個城市靠手藝吃飯,到處充滿優越感的人其實很自卑吧!
這篇文章過不了審覈也無所謂了
/*===可有可無的結尾end===*/