JavaScript >> Javascript 文檔 >  >> JavaScript

了解 CoffeeScript 中的胖箭頭 (=)

粗箭頭(=> ) 是特殊的函數表達式,即使是最聰明的開發人員也會感到困惑。大多數 JavaScript 專業人士都知道閉包會改變 this 的含義 (@ 在 CoffeeScript 中)。

CoffeeScript 中帶有閉包的胖箭頭

例如,我們有一個類,其中 @ 解析為自身,但在嵌套閉包(又名匿名函數定義)中,@window

CoffeeScript 中帶有閉包的胖箭頭

CoffeeScript 代碼:

class A 
  a: ()->
    console.log(@)
    b=()-> console.log(@)
    b()

a = new A
a.a()

JavaScript 代碼:

var A, a;

A = (function() {
  function A() {}

  A.prototype.a = function() {
    var b;
    console.log(this);
    b = function() {
      return console.log(this);
    };
    return b();
  };

  return A;

})();

a = new A;

a.a();

在 CoffeeScript 網站上親自嘗試一下。

這是 CoffeeScript 中粗箭頭最常見的用法。這個案例還包括無所不在的 jQuery 事件處理程序、點擊、mousedowns、mouseup 等。

CoffeeScript 中帶有類的胖箭頭

當我們嘗試應用 => 時,編譯的 JavaScript 代碼會變得有點棘手 在對象/類上。但是,控制台中的結果是相同的,兩個日誌都為 this 輸出相同的對象 :

CoffeeScript 中帶有類的粗箭頭

CoffeeScript 代碼:

class A 
  a: ()->
    console.log(@)
    b=()-> console.log(@)
    b()
  c: ()=>
    console.log(@)

a = new A
a.a()
a.c()

JavaScript 代碼:

var A, a,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

A = (function() {
  function A() {
    this.c = __bind(this.c, this);
  }

  A.prototype.a = function() {
    var b;
    console.log(this);
    b = function() {
      return console.log(this);
    };
    return b();
  };

  A.prototype.c = function() {
    return console.log(this);
  };

  return A;

})();

a = new A;

a.a();

a.c();

在 CoffeeScript 網站上親自嘗試一下。

那有什麼區別呢?我們應該只在對象方法上使用粗箭頭而不是細箭頭嗎?如果我們在控制台中展開對象,事情就會變得更清楚,並觀察到它有 兩個 方法 c() !一個在原型中,另一個在實例中:

胖箭保護方法

當我們調用這些方法時,區別很微妙,但請記住 JavaScript 是一種原型語言。如果可以擴充父類,並且從該類擴展的所有實例都跟隨原型的變化。所以如果我們增加 A.a()A.c() 之後的方法 我們創建 a 對象,a.a() 將在 a.c() 時更新 將保持不變(console.log(@) ):

胖箭法沒變

CoffeeScript 中帶有函數的胖箭頭

粗箭頭的另一種用法涉及將函數傳遞給另一個對象。在這種情況下 -> => 方法丟失了對最初編寫它的類/對象的引用 方法即使在外部環境中也會跟踪它:

CoffeeScript 中帶有函數的粗箭頭

CoffeeScript 代碼:

[旁注]

閱讀博客文章很好,但觀看視頻課程更好,因為它們更具吸引力。

許多開發人員抱怨 Node.js 上缺乏負擔得起的高質量視頻材料。觀看 YouTube 視頻會讓人分心,花 500 美元購買 Node 視頻課程很瘋狂!

去看看 Node University,它有關於 Node 的免費視頻課程:node.university。

[旁注結束]

class A 
  x: ()->
    console.log(@)
  y: ()=>
    console.log(@)

f = (callback)->  
  callback()

a = new A
a.x()
a.y()
f(a.x)
f(a.y)

JavaScript 代碼:

var A, a, f,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

A = (function() {
  function A() {
    this.y = __bind(this.y, this);
  }

  A.prototype.x = function() {
    return console.log(this);
  };

  A.prototype.y = function() {
    return console.log(this);
  };

  return A;

})();

f = function(callback) {
  return callback();
};

a = new A;

a.x();

a.y();

f(a.x);

f(a.y);

在 CoffeeScript 網站上親自嘗試一下。

關於 CoffeeScript 中胖箭頭的結論

沒有理由害怕 CoffeeScript 中的粗箭頭。當涉及到嵌套函數和 jQuery 事件處理程序時,它們可以節省時間(和清晰的實現者)。當它們應用於類方法時,好的經驗法則是:使用 => 當我們需要 @ 成為編寫方法的對象;使用-> 當我們需要 @ 成為執行方法的對象。


Tutorial JavaScript 教程
  1. 用於 Web 身份驗證的密鑰

  2. 幾個值得注意的 TypeScript 播客集

  3. 將數據從 Google 文檔側邊欄推送到 Google 表格

  4. 使用異步函數作為條件

  5. 移動設備上的 HTML 拖放

  6. 為我自己:解釋行動

  7. Drupal 8 自定義塊模塊開發

  1. 如何跟踪或調試所有可用的 JavaScript 事件

  2. 優化 Angular 應用程序的技巧

  3. 如何在 Blogger 中添加 JavaScript?

  4. 一個回購所需的一切

  5. JS - 拆分字符串並循環遍歷結果

  6. 為什麼我要逐步淘汰三元語句

  7. 3.2 認真對待 Firebase V9 - 使用 Firebase 模擬器

  1. Git 的底層

  2. 在 deno 應用程序中保持苗條

  3. Razzle 入門:React 的另一種 SSR 框架

  4. 創建 React 組件生成器