如何使用咖啡脚本使用`this`和`_this`(胖箭头)?

Posted

技术标签:

【中文标题】如何使用咖啡脚本使用`this`和`_this`(胖箭头)?【英文标题】:How to use `this` and `_this` (fat arrow) using coffeescript? 【发布时间】:2012-06-12 01:17:30 【问题描述】:

我正在使用 D3 函数each,它接受一个回调函数并将this 作为参数传递,但我需要同时访问this_this。这是咖啡脚本代码:

@x = d3.scale.ordinal().domain(d3.range(@model.geneExpressions[0].length)).rangeBands([0, width])    

getRow = (row) =>
    cell = d3.select(this).selectAll(".cell")
        .data(row)
      .enter().append("rect")
        .attr("x", (d,i) => @x(i))    

rows = @heatmap.selectAll(".row")
    .data(@model.geneExpressions)
  .enter().append("g")
    .each(getRow)                    

以及它生成的 javascript

    var _this = this;    

this.x = d3.scale.ordinal().domain(d3.range(this.model.geneExpressions[0].length)).rangeBands([0, width]);    

getRow = function(row) 
        var cell;
        return cell = d3.select(_this).selectAll(".cell").data(row).enter().append("rect").attr("x", function(d, i) 
          return _this.x(i);
        )
      ;    

rows = this.heatmap.selectAll(".row").data(this.model.geneExpressions).enter().append("g").attr("class", "row").each(getRow);

我怎样才能让咖啡脚本在这一行中使用 this 并保持一切不变?:

return cell = d3.select(this) ...

问题是我不能将@x 作为参数传递给each 并使用细箭头而不是粗箭头(因为那时我无法访问@x),除非我重写了D3 函数,这似乎有点矫枉过正。

【问题讨论】:

【参考方案1】:

所以你有这样的结构:

@x = ...
getRow = (row) =>
    d3.select(@)...attr('x', (d, i) => @x(i))
rows = ...each(getRow)

但是您需要 getRow 成为普通的 -> 函数,以便它获取 DOM 元素为 @ 并且您需要 attr 回调绑定 => 函数所以 @x 有效,对吧?

立即想到两种可能性:

    使用常用 JavaScript var that = this; 技巧的 CoffeeScript 形式。 为attr 回调使用命名绑定函数。

第一个看起来像这样:

that   = @
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", (d,i) -> that.x(i))    

第二个是这样的:

x_at_i = (d, i) => @x(i)
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", x_at_i)

【讨论】:

以上是关于如何使用咖啡脚本使用`this`和`_this`(胖箭头)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用javascript函数包装器(在coffeescript中添加)“.call(this)”

减少咖啡脚本中的循环

使用 karma 持续编译和运行我的咖啡脚本测试

CoffeeScript - 如何在 ruby​​ on rails 中使用咖啡脚本?

如何使用 nodejs 运行咖啡脚本文件? [复制]

使用需要 grunt 找不到模块“咖啡脚本”