lmartins
3/28/2014 - 12:29 PM

JS Closures in Coffeescript

JS Closures in Coffeescript


# CLOSURES
showName = (firstName, lastName) ->
  nameIntro = "Your name is "
  makeFullName = ->
    console.log nameIntro + firstName + " " + lastName

  return makeFullName()

showName("Michael", "Jackson")

# $ ->
#   selections = []
#   $(".niners").click -> # this closure has access to the selections variable
#     selections.push @prop("name") # update the selections variable in the outer function's scope


celebrityName = (firstName) ->
  nameIntro = "This celebrity is "

  lastName = (theLastName) -> # this inner function has access to outer function variables, including the parameter
    console.log nameIntro + firstName + " " + theLastName

  return lastName

mjName = celebrityName "Michael" # at this juncture, the celebrityName outer function has returned

# the closure lastName is called after the outer function has returned above
# yet, the closure still has access to the outer function's variables and parameter
mjName "Jackson"


celebrityID = ->
  celebrityID = 999
  # we are returning an object with some inner functions
  # all the inner functions have access to the outer function's variables
  getID: ->
    # this inner function will return the UPDATED celebrityID variable
    # it will return the current value of celebrityID, even after the changeTheID function changes it
    console.log celebrityID

  setID: (theNewID) ->
    # this inner function will change the outer function's variable anytime
    celebrityID = theNewID

mjID = celebrityID()  # ath this juncture the celebrityID outer function has returned
mjID.getID()
mjID.setID(567) # changes the outer function's variable
mjID.getID() #it returns the updated variable


celebrityIDCreator = (theCelebrities) ->
  uniqueID = 100
  for celebrity, i in theCelebrities
    theCelebrities[i].id = (j) -> # the j parameter variable is the value of i passed in on invocation of this IIFE
      (->
        uniqueID + j
      )()
    (i)

  theCelebrities

actionCelebs = [
  name: "Stallone"
  id: 0
,
  name: "Cruise"
  id: 0
,
  name: "Willis"
  id: 0
]

createIdForActionCelebs = celebrityIDCreator(actionCelebs)
stalloneID = createIdForActionCelebs[0]
console.log stalloneID.id


# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

foo = (x) ->
  tmp = 3
  (y) ->
    console.log "Resultado: #{x + y + (++tmp)}"

bar = foo(2)
bar(10) # 2 + 10 + 4 = param de foo + param de bar + valor actual de variavel tmp
bar(1) # 2 + 1 + 5
bar(0) # 2 + 0 + 6

foo2 = (x) ->
  tmp = 3
  (y) ->
    console.log x + y + tmp
    x.memb = (if x.memb then x.memb + 1 else 1)
    console.log "O x.memb resulta em: #{x.memb}"

age = new Number(2)
bar = foo2(age)
bar(10)  # 2 + 10 + 3
bar(10)

console.log age.memb


makeFunc = ->
  name = "Mozilla"
  displayName = ->
    console.log name

  return displayName

myFunc = makeFunc()
myFunc()


makeAdder = (x) ->
  (y) ->
    x + y

add5 = makeAdder(5)
add10 = makeAdder(10)

console.log add5(2)
console.log add10(2)


makeSizer = (size) ->
  ->
    document.body.style.fontSize = size + 'px'
    console.log size

size12 = makeSizer(12)
size14 = makeSizer(14)
size16 = makeSizer(16)

#document.getElementById('size-12').onclick = size12
#document.getElementById('size-14').onclick = size14
#document.getElementById('size-16').onclick = size16


makeCounter = ->
  _privateCounter = 0

  _changeBy = (val) ->
    _privateCounter += val

  increment: ->
    _changeBy(1)

  decrement: ->
    _changeBy(-1)

  value: ->
    return _privateCounter

Counter1 = makeCounter()
Counter2 = makeCounter()

Counter1.increment()
Counter1.increment()
Counter1.increment()
Counter2.increment()
console.log Counter1.value()
console.log Counter2.value()


showHelp = (help) ->
  document.getElementById('help').innerHTML = help

makeHelpCallback = (help) ->
  ->
    showHelp(help)

setupHelp = ->
  helpText = [
    'id': 'email', 'help': 'Your email address'
  ,
    'id': 'name', 'help': 'Your full name'
  ,
    'id': 'age', 'help': 'Your age (you must be over 16)'
  ]

  for helper in helpText
    document.getElementById(helper.id).onfocus = makeHelpCallback (helper.help)
  return

setupHelp()



class Animal
  constructor: (@name, @species, @gender) ->

Animal::move = ->
  console.log "#{@name} is moving..."

Animal::talk = ->
  console.log "#{@name} says hi..."


class Dog extends Animal

Dog::talk = ->
  console.log "#{@name} is barking..."


dog = new Dog "Tico", "Dog", "Male"
console.log dog

dog.move()
dog.talk()