Reference to "this" changed inside Sortables Class - mootools

I was testing Jakobs patch on the Sortables Class and this line this.reset() gave me a Uncaught TypeError: undefined is not a function.
I don't understand why since the Class has a method reset.
So my solution was to a var self = this; inside the same end: method (here), and called self.reset(); in the same line as I had this.reset(); before. Worked good. Why?
Then just to check (I suspected already) I did a console.log(this == self) and gave false.
Why does using self work but not this?
Fiddle

In javascript the this keyword change accordingly with the execution context
in global code this refer to the global object
inside eval the scope is the same as the calling context one, if no context provided then is the same as above
in all the case below if the this argument passed to .bind .call or .apply is not an object (or null) this will be the global object
when using a function which has been binded to a specific object using .bind then this refers to the this argument passed to bind, the function is now permabinded.
when running a function the context is provided from the caller, if before the function call operator () there is a dot(.) or a [] operator then this refers to the part on the left of such operator, unless the function is permabinded to something else or we are using .call or .apply if so this refers to the this argument unless the function was previously permabinded;
if before the function call operator () there neither the . nor the [] operators then this will refer to the global object (unless the function stores the result of the .bind function)
when running a constructor function (basically when using new) this refers to the object we are creating
now when using the use strict directive things changes a bit, mostly instead of the global object when the context is not given this will be null, but not in all the cases.
I rarely use "use strict" so I just suggest to try it by yourself when in need.
now, what happens when a function is cached inside a variable like this:
var cache = 'A.foo'
if that you lose the context in which the original function was stored, so in this case foo will not be anymore a property on the instance A and when you run it using
cache()
the context will be evaluated using the rules I wrote above in this case the this will refer to the global object.

The semantics of "this" in Javascript are not what is expected by OO programmers. The symbol "this" refers to the dynamic/runtime calling context, not the lexicographic context. For example, if you have an object A with "method" and then do B.method = A.method; B.method(); then the context is now B and that is what this will point to. The difference becomes very apparent in "handler" type situations where the calling context is usually the object with the handler installed.
Your solution using self is sound.

kentaromiura's answer is absolutely right.
That said, mootools provides function.bind() as a way to decide what this will refer inside of your function. this means that if you simply do this :
var destroy = function () {
`bind() [...]
this.reset();
}.bind(this);
it will work as you intended (that is, this will be the same inside of destroy() and outside).
Now, a lot of coders will balk at fiddling with the context, with good reason as it is very difficult to read and maintain. But here you have it and I think bind() is a very nifty trick of mootools.

Related

What is a function prototype in Rust?

I wanted to understand the behaviour of the #[inline] attribute in Rust, so I was reading through the Attributes section of The Rust Reference. It was very helpful, but I found this part of the description confusing (emphasis mine):
The inline attribute suggests to the compiler that it should place a copy of the attributed function in the caller, rather than generating code to call the function where it is defined.
This attribute can be used on functions and function prototypes, although it does not do anything on function prototypes.
This caveat is repeated for the #[cold] attribute.
I've never heard the term "function prototype" used with respect to Rust. I know that such a concept exists in JavaScript, but JavaScript's and Rust's object and type systems are very different! What does it mean here?
Searching further, I found two mentions of function prototypes in the Error Index:
E0034
The compiler doesn't know what method to call because more than one method has the same prototype.
E0580
The main function was incorrectly declared. The main function prototype should never take arguments.
In this case, "function prototype" seems to mean something like "function signature" -- the names, arguments, and types that make up a function's external interface. This also appears to be what it means in the context of C/C++. However, that doesn't seem to match the usage above; every function definition starts with the function's signature, so it wouldn't make sense to say that putting the attribute on the signature does nothing, because that's what you're doing when you're putting the attribute on a function.
What does the term "function prototype" mean in the context of Rust?
However, that doesn't seem to match the usage above; every function definition starts with the function's signature, so it wouldn't make sense to say that putting the attribute on the signature does nothing, because that's what you're doing when you're putting the attribute on a function.
Yes, every function starts with a signature, but not every signature is part of a function definition. That is, it is possible to have a signature, but no body (in a trait for example) and that's what is meant by "prototype" in the documentation you cited. Something like this:
trait Foo {
#[inline] // This annotation does nothing
fn foo();
}

ES6 default parameter not defined in arguments

Default parameters aren't assigned to the arguments Array like Object :
function fn(test = "test") {
console.log(arguments); //[]
}
This might be usefull to know only what the user passes to the function, but it seems tricky too.
Will this change?
No, this will not change.
In fact it already did change - previously every index on the arguments object was mapped to the respective parameter variable for reading and writing (a horror to reason about!). This proved to have devastating performance implications as it prevented a lot of engine optimisations, and was deprecated in ES5 (however, for compatibility reasons, only in the new strict mode). In ES6, the behavior is also deprecated in sloppy mode functions if they use new ES6 features in their parameter list (like destructuring, default initialisers or rest syntax).
The arguments object is just a simple object with the argument values that were passed to the function. Notice that defaults are not passed, it's just syntactic sugar for initialising variables in the begin of the function body.
If mapped to scope variables, it's much more complicated.

Method's property [[HomeObject]] in Ecmascript 6 [duplicate]

I know that every JavaScript object has an internal property called [[Prototype]]. Some implementations allow access to it via a property called __proto__ while other do not. Is there any special significance of the brackets surrounding this property?
It is an "internal property" of the object. From ECMAScript 8.6.2:
This specification uses various internal properties to define the semantics of object values. These internal properties are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon internal properties in the manner described here. The names of internal properties are enclosed in double square brackets [[ ]].
The statement, "These internal properties are not part of the ECMAScript language," means that internal properties are not identifiers that can be used in actual code -- internal properties are not accessible as members of the objects that contain them. However, they may be made accessible by particular functions or properties (e.g., some browsers are kind enough let you set and get [[Prototype]] through the __proto__ property, and the ES5 spec allows read-only access through Object.getPrototypeOf).
The use of double brackets over single brackets is probably to avoid any possible confusion with actual bracket notation (i.e., property access).
JavaScript [[Prototype]]
The double bracket [[Prototype]] is an internal linkage that ties one object to another.
When creating a function, a property object called prototype is being created and added to the function's name variable (that we call constructor). This object points to, or has an internal-private link to, the native JavaScript Object).
Example:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object 'property' called prototype
// prototype was created automatically when we declared the function Foo.
// Now, we can assign properties to it without declaring the prototype object first.
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
Now, if we'll create a new object out of Foo using the new keyword, we basically creating (among other things) a new object that has an internal link to the function's prototype (Foo) we discussed earlier:
var obj = new Foo();
obj.__proto__ === Foo.prototype // true
obj.[[Prototype]] === Foo.prototype // true
as
obj.__proto__ === obj.[[Prototype]] // true
Since [[Prototype]] is a private linkage to that function's object, many browsers are providing us with a public linkage instead. That is the __proto__ (pronounced as dunder proto).
__proto__ is actually a getter function that belong to the native JavaScript Object and returns the internal-private prototype linkage of whatever the this binding is (returns the [[Prototype]] of obj):
obj.__proto__ === Foo.prototype // true
BTW, starting from ES5, we can use the getPrototypeOf method to get the internal private linkage:
obj.__proto__ === Object.getPrototypeOf(obj) // true
NOTE: this answer doesn't intend to cover the whole process of creating new objects or new constructors, but to help better understand what is the [[Prototype]] and how it works.
The reason it's in brackets is to denote that it's a private property. The brackets themselves are never used in code anywhere.
As you pointed out, some implementation provide access to that private property under __proto__, but it's non-standard.

Actionscript: How exactly does ExternalInterface.addCallback() work?

I'm pretty new to ActionScript, but not new to either object oriented or procedural languages in general. ActionScript's particular combination of features from both categories, however, confuses me.
Specifically, I'm confused about the mechanism of ExternalInterface.addCallback(). The method signature is:
public static function addCallback(functionName:String, closure:Function):void
Of particular interest is the closure parameter, which has the following documentation:
closure:Function — The function closure to invoke. This could be a free-standing
function, or it could be a method closure referencing a method of an
object instance. By passing a method closure, you can direct the
callback at a method of a particular object instance.
I take the above to mean that closure only be a function (not a method), which may or may not be a closure containing a method call from an instantiated object. So I get confused when I see code like this (taken from the same documentation page):
public class ext_test extends Sprite {
function ext_test():void {
ExternalInterface.marshallExceptions = true;
ExternalInterface.addCallback("g", g);
try {
ExternalInterface.call("throwit");
} catch(e:Error) {
trace(e)
}
}
function g() { throw new Error("exception from actionscript!!!!") }
}
The above code inserts in to addCallback, a non-static method of ext_test without wrapping it in a closure containing an instantiated ex_test object.
The method contains trivial code, but what if it were to have statements containing member variables and the like? How would the method be evaluated when it has no parent object?
Furthermore, (since the addCallback seems to allow the passing of arbitrary methods) the documentation makes no mention on the effect access modifiers have on the passed methods, if any. If I label a method private, am I still able to pass it to addCallback? What's the deal?
I'd appreciate it if anyone can help me wrap my head around this.
If your concern is to know in what context the method you passed will be executed, this is simply the context in which you attached it.
The doc's jibber jabber simply means that there are several kinds of function in AS3 and the runtime. "Free-standing" function refers to what you usually call an anonymous function - that still preserves the context in which they were defined :
var anonymous:Function = createAnonymous();
trace(anonymous()); // 123
function createAnonymous():Function {
var internalStuff:Number = 123;
var func:Function = function():Number {
return internalStuff;
}
return func;
}
Methods closures are instances of your classes' methods, the same way objects are instances of these classes. So, when you pass a method closure to ExternalInterface.addCallback(), you'll be safe about the context (i.e. member variables) when it will be invoked.
Woops. Totally forgot the that in all the examples I've seen, addCallback is being executed in the context of a constructor, so the method references passed to it have a context to execute under.
As such, access modifiers don't matter since everything in a class can be seen by the class.

Is there a way to avoid using 'call' in Coffeescript?

I'm writing a simple Twitter client to play with coffeescript. I have an object literal with some functions that call each other via callbacks.
somebject =
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize( this.afterLogin.call this )
afterLogin: ->
this.getTweets(this.pollinterval)
This code works perfectly. Edit: actually this.afterlogin should be sent as a callback above, not ran immediately, as Trevor noted below.
If, within authenticateAndGetTweets, I removed the 'call' and just ran:
oauth.authorize( this.afterLogin )
and don't use 'call', I get the following error:
Uncaught TypeError: Object [object DOMWindow] has no method 'getTweets
Which makes sense, since 'this' in afterLogin is bound to the thing that initiated the callback rather than 'someobject' my object literal.
I was wondering if there's some magic in Coffeescript I could be doing instead of 'call'. Initially I thought using the '=>' but the code will give the same error as above if '=>' is used.
So is there a way I can avoid using call? Or does coffeescript not obviate the need for it? What made '=>' not work how I expected it to?
Thanks. I'm really enjoying coffeescript so far and want to make sure I'm doing things 'the right way'.
As matyr points out in his comments, the line
oauth.authorize( this.afterLogin.call this )
doesn't cause this.afterLogin to be called as a callback by oauth.authorize; instead, it's equivalent to
oauth.authorize this.afterLogin()
Assuming that you want this.afterLogin to used as a callback by oauth.authorize, megakorre's answer gives a correct CoffeeScript idiom. An alternative approach supported by many modern JS environments, as matyr points out, would be to write
oauth.authorize( this.afterLogin.bind this )
There's no CoffeeScript shorthand for this, partly because Function::bind isn't supported by all major browsers. You could also use the bind function from a library like Underscore.js:
oauth.authorize( _.bind this.afterLogin, this )
Finally, if you were to define someobject as a class instead, you could use => to define afterLogin such that it's always bound to the instance, e.g.
class SomeClass
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize(this.afterLogin)
afterLogin: =>
this.getTweets(this.pollinterval)
someobject = new SomeClass
you can put a lambda in the function call like so
auth.authorize(=> #afterLogin())
You have to use either the call or apply methods because they set the scope of the function (the value of this). The error results because the default scope is the window object.