JavaScript call by reference 設計架構下的有趣問題

JavaScript 最近聽說火紅的很,寫起來是真的很方便很快速,學他要用來快速實踐某個想法功能(演算法)也是很不錯!

但朋友最近在接觸 ES6 後丟了一個問題來考考我,一考就爆了XD

弱...

其實不是在於理解問題,而是如何解!

var cmds = ['get','post','put','del']

var request = {}

for (var key in cmds){
  var c = cmds[key]; 
  request[c] = function(){
    console.log(c);
  };

}
request.post();

如果反應正確,看完上面的code後,腦袋的輸出會是 post

但!

是輸出 del

登愣 Orz

因為 JavaScript 中的那個 var c = ... 在每次循環時都被洗掉改指向新的值,而最後每個對應方法都被改指到最後一組,所以答案就跑走。

解法有兩個情況:

ES5 解

var cmds = ['get','post','put','del']

var pro_request = {}
for (var key in cmds){
  var c = cmds[key]
  pro_request[c]= (function(){
    console.log(this.cmd)
  }).bind({cmd:c})
}
pro_request.post()

ES6 解

var cmds = ['get','post','put','del']

var request = {}

for (var key in cmds){
  let c = cmds[key]; 
  request[c] = function(){
    console.log(c);
  };

}
request.post();

ES6 的解法是使用 let 這區域變數存值的呼叫方法,解決問題,而ES5就難看許多,還是先將數值存入物件(Object)後使用bind方法帶入自身,並呼叫物件中的值印出。

但有一個解法更有趣,看這裡線上ES6轉譯的結果

'use strict';

var cmds = ['get', 'post', 'put', 'del'];

var request = {};

var _loop = function () {
  var c = cmds[key];
  request[c] = function () {
    console.log(c);
  };
};

for (var key in cmds) {
  _loop();
}
request.post();

直接把變數都包給每個方法去了~ 真神奇寫法XD

Facebook 外掛功能


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *