dongtiaozhou4914 2017-01-12 06:40
浏览 54
已采纳

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

Below are two code snippets - one in Go and the other in JavaScript - essentially doing the same thing.

// Go

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

Output

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

Output

Engine starting in undefined seconds ...

I know the workaround in JavaScript, but that's not the question. Why did JavaScript decide not to retain the original execution context of a function?

  • 写回答

1条回答 默认 最新

  • douxing8939 2017-01-12 08:48
    关注

    Here in javascript the function is not bind to the object engine when you pass the object to BenchmarkSuite constructor.

    You have to explicitly bind the object to the function. This is what you have to do

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

    The simplest use of bind() is to make a function that, no matter how it is called, is called with a particular this value. A common mistake for new JavaScript programmers is to extract a method from an object, then to later call that function and expect it to use the original object as its this (e.g. by using that method in callback-based code). Without special care however, the original object is usually lost. Creating a bound function from the function, using the original object, neatly solves this problem

    You may refer here for more

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

    </div>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?