箭頭函數和let、const聲明小總結

/*===可有可無的開頭start===*/
最近由於一些事兒辭了剛剛找到的工做,處在待業狀態,去稍微的面了幾家公司,有大有小,有好有壞,發現你們問起來的一些ES6的問題跟我想的不同,下來再去研究發現我說的仍是有些缺陷,雖然意思是對的,可是表達的很奇怪,怪不得面試官會誤會,參考了下以前公司大哥的一些和網上大神的,這裏撿着關於箭頭函數和let、const去說一些淺陋的總結(都是爛大街的啦~)
/*===可有可無的開頭end===*/前端

文中大部分偏建議,結合了網上的一些規範整理出來的,也包括了一些特殊的數組和對象的處理。後期你們一塊兒討論

1、函數聲明的不一樣使用方式

ES6中兩種方式進行函數的定義:箭頭函數 和 function()面試

箭頭函數的區別1: 沒有本身的this,它的this來自它定義時的環境數組

箭頭函數的區別2: 由於沒有本身的this,因此bind、apply、call也對其不起做用閉包

箭頭函數的區別3: 內部不能使用argumentsapp

因此總結起來就是,只要是須要用到內部的this和arguments的狀況下,就不能使用箭頭函數,這是一個基礎,感受上只要注意這個,這兩個能夠隨便用,下面總結了一下dom

1. 不適合用箭頭函數的場景

1) 綁定事件的回調中使用this去表明當前綁定的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'
})

2) 定義構造器(工廠方法)時箭頭函數不能使用

// 普通形式(正確)
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

3) 定義對象的方法屬性時用到了this指向當前對象的時候

// 普通方式(正確)
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

4) 使用arguments的場景

// 正確的
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
}

5)要應用到bind、apply、call的時候

由於箭頭函數沒有this的狀況,因此bind、apply、call對其不起做用,若是一個方法定義出來須要用在這個場景下,那麼不能使用箭頭函數(例如一個函數須要被進行柯里化的操做)函數

2. 適合用箭頭函數的場景

只要不涉及到this和arguments,箭頭函數就可使用this

箭頭函數的優點:rest

  1. 簡單快捷
  2. 能夠利用其this的繼承性減小外層this的傳遞

如下是適用場景code

1) 在 map、reduce、filter 的回調函數定義

let arr = [1,2,3]
arr.map((val)=>val+1); //[2,3,4]

2) 當即執行

((msg)=>{console.log(msg)})('this is a test'); //'this is a test'

3) 須要傳遞外部this的狀況(閉包或者做用域內定義的函數)

// 很差的使用
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'

2、使用let和const替換掉var

let和const指令針對於塊級做用域,基本上能替換掉var的變量聲明

1.let和const的使用上的區分:

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;
}

2. 替換var的時候由須要注意:

1)let 和 const 不會進行做用域內的提高

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

2)let在for循環中的定義

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,可是也是受盡了互聯網公司人資的歧視(居然反問我以前軟件公司還須要加班麼)

最近去了某互聯網媒體巨頭某狐面試,經歷了史無前例的人力面,在她滿臉看不起個人在軟件公司幹了兩年的工做經驗中,我當心翼翼的回答着她挑釁的問題,自稱互聯網人的她對我以前的公司反覆的羞辱和鄙視,我也是不卑不亢(畢竟我只是去試試感受),在最後問我爲何大四上半年就簽了工做,是否是不敢去互聯網公司試試,仍是說大四下半年在忙着補考。而後我說把手機裏的成績單給她看(哈哈,大學仍是有點小成就的),她居然說我是有備而來,嗯,能夠,大公司咄咄逼人吶

還有一些肉眼可見直插肺腑的地域歧視

這裏也總結一下我被問到的問題

  1. 任丘是哪的啊,你下次直接寫到滄州就行了
  2. 哦,我去過滄州,感受挺亂的
  3. 你從縣城來,怎麼沒有回家考公務員
  4. 大家軟件公司還加班?大家加班幹什麼啊?
  5. 大家大學是華北電力大學在保定的分校麼,是那個三本麼
  6. 你的夢想是什麼,咱們公司都是有夢想的人,你沒夢想可不行

···

我家是河北滄州任丘,特別乾淨,由於考不上公務員才被迫來北京謀生,我以前的軟件公司也很厲害,早就不是用JSP寫前端頁面了,加班是我熱愛我作的工做,咱們大學是正正經經的重本大學,我上學那會兒保定的分不比北京低,我沒有夢想,由於我不是汪峯,你們都是在這個城市靠手藝吃飯,到處充滿優越感的人其實很自卑吧!

這篇文章過不了審覈也無所謂了

/*===可有可無的結尾end===*/

相關文章
相關標籤/搜索