javascript - 这两个实现有什么不同

标签 javascript coffeescript this

片段A:

DemoFilter =
  onConfirmed: (cb) ->
    cb()
a =
  onConfirmed: (callback) ->
    this.callback = callback
  confirm: ->
    this.callback()

b =
  init: ->
    a.onConfirmed =>
       DemoFilter.onConfirmed @mycallback
  mycallback: =>
    console.log this # output: {} or Object window on browser

b.init()
a.confirm()

片段 B:

DemoFilter =
  onConfirmed: (cb) ->
    cb()
a =
  onConfirmed: (callback) ->
    this.callback = callback
  confirm: ->
    this.callback()

b =
  init: ->
    a.onConfirmed =>
       DemoFilter.onConfirmed =>
         console.log this # output: Object b
  # mycallback: =>
  #   console.log this

b.init()
a.confirm()

为什么这些console.log输出不一样?

在节点环境中:

A:输出{}
B: 输出对象b

我发现编译结果完全一样,我想不通为什么结果不一样。

最佳答案

这里的问题是您使用的是简单的对象而不是类,因此 => 的行为不符合您的预期。当你这样说时:

o =
  m: =>

这和说完全一样:

f = =>
o =
  m: f

这意味着 m 中的 @(又名 this)是全局对象(window in a浏览器或者 AFAIK,node.js 中的一个空对象)而不是你期望的 o

当你说:

class C
  m: =>

当您说o = new C 时,CoffeeScript 会将m 绑定(bind)到C 实例。如果您使用普通对象文字而不是类,则没有特殊的构造阶段来设置绑定(bind),也没有类的实例供 => 将函数绑定(bind)到。

如果我们回到您的第一个案例:

b =
  init: ->
    a.onConfirmed =>
       DemoFilter.onConfirmed @mycallback
  mycallback: =>
    console.log this

mycallback 将绑定(bind)到任何全局对象。此外,@(又名 this)的值取决于函数的调用方式,而不是函数的定义位置(当然不包括绑定(bind)函数),因此如果您说:

b.init()

那么 init 中的 @ 将是 b。然后你交给a.onConfirmed的匿名函数:

a.onConfirmed =>
   DemoFilter.onConfirmed @mycallback

将绑定(bind)到 b,因为当您定义该函数时,@b。但是 mycallback 不会在意,因为它已经绑定(bind)到全局对象。

在你的第二种情况下:

b =
  init: ->
    a.onConfirmed =>
       DemoFilter.onConfirmed =>
         console.log this

当调用 init 并将匿名函数传递给 a.onConfirmed 时,我们再次将 @ 设为 b将再次绑定(bind)到 b。这意味着当:

DemoFilter.onConfirmed => ...

被调用,@ 将再次成为 b。这里我们有另一个匿名绑定(bind)函数,因为 @b 在这个级别我们有 this (AKA @) bconsole.log this 被调用时。

如果您使用的是类而不仅仅是对象:

class A
  onConfirmed: (@callback) ->
  confirm: ->
    @callback()

class B
  constructor: (a) ->
    a.onConfirmed =>
       DemoFilter.onConfirmed @mycallback
  mycallback: =>
    console.log @

a = new A
b = new B(a)
a.confirm()

然后您应该会看到您期望的行为。

关于javascript - 这两个实现有什么不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35702056/

相关文章:

javascript - “Li”元素显示为 `undefined`

javascript - 如何查看内置 JavaScript 函数的源代码?

javascript - jQuery $.each 嵌套在 $.When

javascript - NestJS 在服务类中丢失此内部函数方法的上下文

javascript - 数据表将输入搜索集中在 Bootstrap Modal 上

javascript - 如何在coffeescript中将两个jquery帖子合并为一个?

node.js - 无法读取 node_redis hgetall 函数中未定义的属性 'length'

javascript - 如何访问 CoffeeScript 中的类方法?

javascript - 在 javascript 中,如何在不调用函数的情况下判断函数绑定(bind)到哪个对象(即它的 'this' )?

javascript - 如何从 jQuery 函数访问外部 this?