A continuación se muestran dos fragmentos de código, uno en Go y el otro en JavaScript, que esencialmente hacen lo mismo.

// Ir

package main    

import "fmt"

type Engine struct {
  bootTimeInSecs int
}

func (e *Engine) Start() {
  fmt.Printf("Engine starting in %s seconds ...", e.bootTimeInSecs)
}

type Start func() 

type BenchmarkSuite struct {
  workloads []string
  start Start 
}

func main() {
  engine := Engine{10}
  benchmarkSuite := BenchmarkSuite{workloads: []string{}, start: engine.Start}
  benchmarkSuite.start()
}

Salida

Engine starting in 10 seconds ...

// JavaScript

function Engine(bootTimeInSecs) {
    this.bootTimeInSecs = bootTimeInSecs
}

Engine.prototype.constructor = Engine
Engine.prototype.Start = function() {
  console.log("Engine starting in " + this.bootTimeInSecs + " seconds ...")
}

function BenchmarkSuite(workloads, start) {
    this.workloads = workloads
    this.start = start
} 

BenchmarkSuite.prototype.constructor = BenchmarkSuite

engine = new Engine(10)
benchmarkSuite = new BenchmarkSuite([], engine.Start)
benchmarkSuite.start()

Salida

Engine starting in undefined seconds ...

Conozco la solución alternativa en JavaScript, pero esa no es la cuestión. ¿Por qué JavaScript decidió no retener el contexto de ejecución original de una función?

-3
Bharat Khatri 12 ene. 2017 a las 09:40
Quienquiera que haya votado close sobre la pregunta, ¿puede explicar cómo la pregunta atraería respuestas basadas en opiniones ?
 – 
Bharat Khatri
12 ene. 2017 a las 09:48
Por favor verifique la respuesta, olvidó vincular la función
 – 
Sarath Sadasivan Pillai
12 ene. 2017 a las 14:51

1 respuesta

La mejor respuesta

Aquí, en javascript, la función no se vincula al objeto engine cuando pasa el objeto al constructor BenchmarkSuite.

Tienes que vincular explícitamente el objeto a la función. Esto es lo que tienes que hacer

benchmarkSuite = new BenchmarkSuite([], engine.Start.bind(engine))

El uso más simple de bind () es hacer una función que, sin importar cómo se llame, se llame con un valor particular de este. Un error común para los nuevos programadores de JavaScript es extraer un método de un objeto, luego llamar a esa función y esperar que use el objeto original como este (por ejemplo, usando ese método en código basado en callback). Sin embargo, sin un cuidado especial, el objeto original suele perderse. La creación de una función vinculada a partir de la función, utilizando el objeto original, resuelve perfectamente este problema.

Puede consultar aquí para obtener más información.

function Engine(bootTimeInSecs) {
    this.bootTimeInSecs = bootTimeInSecs
}

Engine.prototype.constructor = Engine
Engine.prototype.Start = function() {
  console.log("Engine starting in " + this.bootTimeInSecs + " seconds ...")
}

function BenchmarkSuite(workloads, start) {
    this.workloads = workloads
    this.start = start
} 

BenchmarkSuite.prototype.constructor = BenchmarkSuite

engine = new Engine(10)
benchmarkSuite = new BenchmarkSuite([], engine.Start.bind(engine))
benchmarkSuite.start()
1
Sarath Sadasivan Pillai 12 ene. 2017 a las 11:48
@ bharat-khatri por favor revise y vote a favor la respuesta si le ayudó: D
 – 
Sarath Sadasivan Pillai
13 ene. 2017 a las 12:35