Go与JavaScript中方法的执行上下文

时间:2017-01-12 06:40:02

标签: javascript go

下面是两个代码片段 - 一个在Go中,另一个在JavaScript中 - 基本上做同样的事情。

// 转到

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()
}

输出

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()

输出

Engine starting in undefined seconds ...

我知道JavaScript中的解决方法,但这不是问题。为什么JavaScript决定不保留 原始函数的执行上下文?

1 个答案:

答案 0 :(得分:1)

在javascript中,当您将对象传递给engine构造函数时,函数不会绑定到对象BenchmarkSuite

您必须将对象显式绑定到函数。 这就是你必须要做的事情

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

bind()的最简单用法是创建一个函数,无论它如何被调用,都使用特定的值调用。新JavaScript程序员的一个常见错误是从对象中提取方法,然后调用该函数并期望它将原始对象用作其对象(例如,通过在基于回调的代码中使用该方法)。然而,如果没有特别小心,原始对象通常会丢失。使用原始对象从函数创建绑定函数,巧妙地解决了这个问题

您可以参考here了解更多信息

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()