Discord
Login
Community
DARK THEME

`Function.bind` method is ineffective, and `this` context is always whatever object the variable is on.

The this context appears to always be whatever object a variable is called from. Function has a method called bind, but it appears to be ineffective at changing the this context of the function. This might be an issue with the re-binding of the variable called this.

otherObj = object
  otherFunc = function(cb)
    cb() // This has re-bound `this` inside of `cb` to `otherObj`
  end
end

// I want to pass a function from within a class instance somewhere else
// that references members of `this`, but when otherFunc calls the passed
// function the `this` variable is re-bound to `otherObj` in either of the
// below cases.
otherObj.otherFunc(function() this.memberFunction() end) // or otherFunc(this.memberFunction.bind(this))

The only way I have found to effectively get around this is to define the function as local, then send call the local function inside of another anonymous function that is passed as a callback. Without the wrapper the local function will suffer from the same bug and have it's this context re-bound to the calling object.

https://microstudio.io/i/Loginus/instance_call/

I noticed that there is a problem with passing an object (A) to call another object (B) and its specific method, e.g. B.testCall, which is not known at the time of writing the code, but only passed in the parameters.

A.constructor = function( inst, method )
 this.inst = inst
 this.method = method
end

A.Call = function()
  this.obj[this.method]()
end

a = new A()
a.setCall( b, b.testCall )
a.Call()

Unfortunately, the A.Call() function will attempt to call you as you would have typed

A.Call = function()
 this.testCall()
end

And if the class does not have the testCall() function, it will throw an error. If a class has a testCall() function, it will call it and you will be surprised how the program works.

Check out my program which avoids this problem in a very complicated way.

The rule is this:

  • you remember the instance of the object you want to call
  • you remember the name of the method you want to call
  • you call instances and methods through an external function (from outside the class - function instanceCall() ).
C = class
 constructor = function( inst, method)
    this.inst = inst
    this.method = method
 end
 Call = function(arg)
    instanceCall(this.inst, this.method, arg)
 end
end

init = function()
 instA = new TestClass( " Instance A")
 c = new C( instA, getNameMethod( instA, instA.printName ))
 c.Call()
end

I have defined my own method to create a new javascript closure that preserves the reference to this. It doesn't take an object to use for the context, though, and just locks the routine into it's original context.

Function.lock = function()
  local self = this
  local create = system.javascript("""
    return (self) => (...args) => self(...args);
  """)
  return create(self)
end

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community