昨天在開發過程中遇到個問題,事情這樣的。
專案中有個頁面基於vue做的 中間用到了el-upload這個元件進行上傳操作。 原來的上傳過程中,檔案限制個數為5個
<el-upload list-type="picture-card" action :http-request="uploadOss" accept=".bmp, .jpg, .png" :limit="5" :disabled="pictureList40.length >5" :on-exceed="limitMax" :before-upload="beforeUpload" :on-preview="handlePreview" :on-remove="(file, fileList) => {handleRemove(file, fileList, 4)}" :file-list="pictureList40" :data="{index:4}" > <i class="el-icon-plus avatar-uploader-icon"></i> </el-upload>
原有limitMax的定義如下:
limitMax() { this.$message.warning("圖片最多上傳5張");},
考慮到新增的這個上傳元件需要限制為10張圖 於是將limitMax()改成如下
limitMax(limit) {
this.$message.warning("圖片最多上傳"+limit+"張");
}
並將 :on-exceed="limitMax" 改成 :on-exceed="limitMax(10)",:limit="5"改成了 :limit="10",:disabled="pictureList40.length >10" 結果執行出現頁面一載入就彈出檔案個數限制提示框 如下圖:
這就奇怪了 明明我都還沒有上傳 檔案 為啥就觸發了檔案個數限制回撥呢。由於本人是後端開發,也只會些jq操作,對vue操作也就停留在個 new vue基礎 上,於是叫來了這邊 的前端工程師。
前端大佬一頓嗨操作,啟動好幾次後,仍舊頁面一加載出現這個提示框。只見他摸著頭,慢慢開啟瀏覽器在百度輸入框輸入 el-upload 迅速回車 一頓滑鼠狂點找到了如下個文件:
看完後 他略有所思的將limitMax(limit) 函式改成了
limitMax(files, fileList, limit) { this.$message.warning("圖片最多上傳" + limit + "張");}
然後將:on-exceed="limitMax(10)" 改成了 :on-exceed="(files, fileList) => limitMax(files, fileList, 10)" 然後快速重啟應用。
奇蹟出現了,頁面載入沒有出現提示框了。
前端工程師瀟灑而去...
晚上下班想到這個事,覺得對這個=>感到陌生,自己也只對->這個比較熟悉(本人後端主要語言是Java) Java中有這種操作,
BiConsumer bi=(x,y)->System.out.println(x);
傳說中的函數語言程式設計。
於是想到是不是=>也是和->一樣的函式定義操作(代替匿名函式,使得程式碼更加簡潔有效,其實本人覺得更加晦澀,可能jdk7玩久了吧)。
於是我也開啟了前端工程師的騷操作,開啟瀏覽器 翻出百度...
ES6標準新增了一種新的函式:Arrow Function(箭頭函式)。
為什麼叫Arrow Function?因為它的定義用的就是一個箭頭:
x => x * x
上面的箭頭函式相當於:
function (x) { return x * x;}
箭頭函式相當於匿名函式,並且簡化了函式定義。箭頭函式有兩種格式,一種像上面的,只包含一個表示式,連{ ... }和return都省略掉了。還有一種可以包含多條語句,這時候就不能省略{ ... }和return:
x => { if (x > 0) { return x * x; } else { return - x * x; }}
如果引數不是一個,就需要用括號()括起來:
// 兩個引數:(x, y) => x * x + y * y// 無引數:() => 3.14// 可變引數:(x, y, ...rest) => { var i, sum = x + y; for (i=0; i<rest.length; i++) { sum += rest[i]; } return sum;}
如果要返回一個物件,就要注意,如果是單表示式,這麼寫的話會報錯:
// SyntaxError:x => { foo: x }
因為和函式體的{ ... }有語法衝突,所以要改為:
// ok:x => ({ foo: x })
this
箭頭函式看上去是匿名函式的一種簡寫,但實際上,箭頭函式和匿名函式有個明顯的區別:箭頭函式內部的this是詞法作用域,由上下文確定。
回顧前面的例子,由於JavaScript函式對this繫結的錯誤處理,下面的例子無法得到預期結果:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); }};
現在,箭頭函式完全修復了this的指向,this總是指向詞法作用域,也就是外層呼叫者obj:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = () => new Date().getFullYear() - this.birth; // this指向obj物件 return fn(); }};obj.getAge(); // 25
如果使用箭頭函式,以前的那種hack寫法:var that = this;這就不需要了。由於this在箭頭函式中已經按照詞法作用域綁定了,所以,用call()或者apply()呼叫箭頭函式時,無法對this進行繫結,即傳入的第一個引數被忽略:
var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); }};obj.getAge(2015); // 25