Context getting mixed in $.deferred.promise - javascript

I have the following code;
function myFunction(promiseObject){
var that = this;
promiseObject
.done(function(){
//using that here
});
}
The above function gets called in multiple context and hence value for this changes in every call. The issue I am facing is that for many concurrent calls, the value for that gets overridden by another context which is also in process of completion.
I wanted to understand what could be the reason for this. Also wanted to understand that what is the concept behind scope of that variable defined in myFunction but used in the attached callback method.
Thanks in advance :)
-devsri

I hope that I understand your problem correctly. The concept behind the that variable being defined in myFunction and being accessible in the callback is lexical scoping at work. It's creating a closure (basically a reference to the execution environment of the function that the callback is defined in) for the callback to access.
The value of this inside of myFunction is going to depend on how you are calling myFunction.
If you want a myFunction to have a specific context you'll need to call it with that context like so:
var myContext = { foo: "bar" };
myFunction.call(myContext);
The value of this inside of myFunction will now be equal to myContext.
If you want your value of that to remain consistent between calls you'll need to make sure you call/apply myFunction with the correct context everywhere.
Alternatively you can use a function like underscore.js's _.bind:
myFunction = _.bind(myFunction, myContext);
myFunction will now always be bound to a specific context.

Related

(this) after function declaration

Can somebody explain me what (this) means at the end of the following code:
var a=(function(_this){
return function() {
//do something
return smth;
};
})(this);
What is the sense of such coding?
Going forward, what does the following code do, when placed in .js file and invoked by html tag?
(function() {
Emitter=(function(){
function Emitter() {}
...
return Emitter;
})();
A=(function(_super){...})(Emitter);
}).call(this);
how to instantiate object A from outside the js file?
This is a self-executing function, which is used to save a reference to "this" through the function's closure. It is used to hold on to the reference to "this" at the function's first execution time.
You can also use Function.prototype.bind() to achieve a similar result of saving a reference to "this":
MDN - Bind
This whole structure is a means of saving the current value of this so that a function call later on can use it.
That could all be done also with .bind() like this which (if you understand what .bind() does might be easier to follow):
function myFunc(_this) {
// do something
}
var a = myFunc.bind(null, this);
Here are the various steps in what happens in the code you've shown:
this will have a value from the surrounding context when this code is originally executed (which you don't show). It is being passed into a self-executing function as an argument often referred to as an IIFE (immediately invoked function expression) which is just a function call that happens immediately inline as the code is initially run.
Within that function it is given an argument name of _this.
When that function executes, it returns another function. The body of that inner function also has access to _this.
When that inner function is returned, it is assigned to the variable a.
The upshot of all this is that one can call a() and the internals of that function, when it executes will be able to access _this which contains the value of the original this.
So, it's essentially a means of creating a function that when executed will have access to the original value of this even though the context will have changed when a() is later called. So, its essentially saving the value of this for a specific function to use later.
More detail would require more context about what is going on inside that internal function, what the this value was in the original context and how a() is used later.
This is one particular use of an IIFE. They have many other uses.

Javascript closures and callbacks - variable value doesn't persist after the callback

I'm wondering why the variable is undefined if it's initialized within a callback function.
Pseudo code:
var name;
//callback function:
function(givenName) {
name = givenName;
}
alert(name) // undefined
The callback function is called from a different module that passes the givenName, and within the callback function name is defined as it should, but not outside the callback function. I'm curious to know how this works and how to get around it. Any articles or answers are more than welcome! thanks.
When this function is called from another context and you want to affect variables in the actual scope you will need to pass the context when calling this method.
Therefore you should use call or apply and pass the desired context as first parameter.
Hope this helps

Correct use of the this pointer in javascript for callbacks in knockout.js

I am a relatively experienced c# (and before that c++ Win32) developer, I am new to javascript and have a question regarding the this pointer.
I am using knockout.js, and one function called subscribe accepts a this variable, that will be set inside the callback function.
From my way of thinking from the Win32 days and C#, on any callback function i want a scope object which contains my state.
In this case I have use the this javascript thing to set my callback scope.
My questions are:
Now everything works (full fiddle here if you are
interested), but have I done something terrible?
Is there any reason this is used instead of passing in an explicit
scope variable as a parameter (that would make things easier to understand as
for me, this makes the workings kind of hidden).
What is the intended use for this?
From http://knockoutjs.com/documentation/observables.html it says:
The subscribe function accepts three parameters: callback is the function that is called whenever the notification happens, target (optional) defines the value of this in the callback function, and event (optional; default is "change") is the name of the event to receive notification for. Example below
myViewModel.personName.subscribe(function(oldValue) {
alert("The person's previous name is " + oldValue);
}, null, "beforeChange");
My code snippet below:
var computedOptions = createComputedDepdency(viewModel[option.requires.target],option.data);
viewModel[option.optionsName] = computedOptions;
console.log("making callback scope object for: " + option.optionsName );
var callbackScope = {
callbackName: option.optionsName,
options: computedOptions,
selectedValue: viewModel[option.selectedName]
};
// when the list of available options changes, set the selected property to the first option
computedOptions.subscribe(function () {
var scope = this;
console.log("my object: %o", scope);
scope.selectedValue(scope.options()[0].sku);
console.log("in subscribe function for..." + scope.callbackName);
},callbackScope);
First a semantic note:
The scope of a function is not related to this word. The context is related to this. The scope is related to the accessibility of variables and functions inside another function.
When you try to read a variable outside the function where it's declared, then you trying to access to a var outside its scope. So you cannot do it because the var is inside a scope not accessible from current position.
Now everything works (full fiddle here if you are interested), but have I done something terrible?
If it works, it's not so terrible :-)
Is there any reason this is used instead of passing in an explicit scope variable as a parameter (that would make things easier to understand as for me, this makes the workings kind of hidden).
a fast read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
In javascript the value of this is determined by how a function is called.
In one way this approach could save annoying passage of context as argument: in a well documented library, the this use is very intituitive.
In other cases, I agree when you change continually context in your app without a rigorous logic, it could be confused.
What is the intended use for this?
We should always remember how and when the javascript is born. It was born for browser in order to interact with the DOM.
For this purpose, the context has sense that change based of which element call the function.
For example:
var divs = document.getElementsByTagName('DIV');
for(var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click',_clickHandler);
}
function _clickHandler() {
this.innerHTML = "clicked";
}
DEMO http://jsfiddle.net/AYBsL/1/
This is an example to how is useful the implicit change of context in javascript.
You could do this also for user-defined function: when you call a function you could change the context:
_clickHandler.call(divs[0]); // simulate click of first div
In javascript 'this' refers to the object that called your function. Only in a situation when you use 'new' keyword you can expect it to point to the current object (function).
var MyObject = function () {
this.hello = function () { console.log(this); }
}
var instance = new MyObject();
There is a way to make sure that this is always what you expect and that is creating a variable to store the correct reference for you and use that instead of this... in your example it would be similar to this...
computedOptions = function () {
var that = this;
}
computedOptions.subscribe(function () {
console.log("my object: %o", scope);
scope.selectedValue(that.options()[0].sku);
console.log("in subscribe function for..." + that.callbackName);
},callbackScope);
MDN JavaScript reference would inevitably explaing it more better then myself, have a look at it.
You shouldn't mix scope and this. this is supposed to mimic classical-oop languages like java or++, that is to keep the reference to an instance object. But it can be used just to execute arbitrary function on a given context using .apply() or .call.
What about scope, you don't have to do anything to pass the scope to a function, since the outer scope becomes automatically accessible inside function. You should read about closures - it's the best part of javascript.

Is there another way to write a function declaration?

It just seems odd to me to write dbr.onsuccess after dbr has been declared.
var dbr = window.indexedDB.open("Matrix");
dbr.onsuccess = function(myEvent) {}
Q: Is there an alternative way to write line 2 (without being Rube Goldberg)? Maybe something like:
function dbr.onsuccess(myEvent) {
}
I'm just concerned about the order of things. To me, it seems that it's too late to assign an onsuccess function to dbr after it's been created.
var dbr = window.indexedDB.open("Matrix");
is an asynchronous request.
Async requests run in the background and won't run their callbacks until the function completes. So all of the other assignments will happen before any callback functions are run.
The indexedDB is returning you an interface object so that you can define exactly what those callback functions are. You can think of it as you making a request
Hey I want to open matrix
and getting a response back saying
Hey, I'm working on that, here's an object. Please list what you want to have happen when I finish on it.
Then, when it has completed the open operation (and the current function context has completed running) it will look at that object and run accordingly.
The return value of open isn't the real result of the function, its just an object returned for you to tell it what to do. This is similar to a promise/deferred way of doing things, which is different from the normal JS callback model.
This:
function dbr.onsuccess(myEvent) {
}
is not valid syntax. You can't define a property on an object till the object itself has been defined, and javascript doesn't support function declarations for properties. They're only used for top level objects.
dbr.onsuccess = function(myEvent) {}
This is technically a function expression, as it's an assignment statement to the onsuccess property of dbr.
So when you ask if there is more than one way to write a function declaration, the answer is technically no.
A function declaration has only one form:
function foo() {}
Your suggested syntax to declare a function as a property of an object is interesting but a wrinkle in the idea is function hoisting. As you probably already know, functions (including their definitions) available anywhere within scope, even preceding code. Take this example:
foo.bar();
var foo = getFoo();
function foo.bar() {}
Due to function hoisting, foo.bar should be available on line 1. But due to variable hoisting, foo is declared but not yet defined. On line 1 foo has a value of undefined and would result in a TypeError if you tried to invoke function foo.bar.
I think you can say:
var dbr = window.indexedDB.open("Matrix").onsuccess = function(myEvent) {}

accessing eval'd code through setInterval/setTimeout

i am wondering if i can do some cleanup routines that will auto grab timeouts / intervals. consider this:
var timeout = setInterval(function dimitar() {
console.log("hi!");
}, 1000);
console.log(window);
i had a look through window and can't find any reference to the function that's been passed on. the reference to timeout is there, sure enough. so where does the function 'live' here? is it launching a new instance of the js interpreter to eval/run/keep the code? how can you access it in relation to the timeout uid?
i know i can curry the setInterval function and get it to always store the reference into an array which i can then loop through and clear, but am curious if there's a natural way of doing this
The function you create in your example is using a named function expression. The name is only available within the function. Otherwise, it behaves the same as an anonymous function: you haven't assigned it to a variable and since it's not a function declaration, it doesn't create a dimitar variable in the enclosing scope. The following article may be useful: http://yura.thinkweb2.com/named-function-expressions/
There's no eval-type thing going on: you've just passed in a reference to a function into window.setInterval. This function cannot be retrieved afterwards unless you've assigned it to a variable previously, or it was a reference to a function defined by a function declaration.
If you want to keep a reference to the function around, it's simply a matter of storing it in a variable first:
var dimitar = function() {
console.log("hi!");
};
window.setInterval(dimitar, 1000);
so where does the function 'live' here?
The timeout/interval queue is an internal implementation detail that's not accessible to content JavaScript. It retains a reference to the function passed in to setInterval, but it's not a reference that's visible to you.
Incidentally you should generally avoid using named inline function expressions. Although it's probably OK in this example code, IE's JScript has some serious basic bugs with them that can trip you up if you're not careful. Stick to named function statements (function dimitar() { ... } ... setInterval(dimitar, 1000)) or anonymous inline function expressions (setInterval(function() { ... })).
is it launching a new instance of the js interpreter to eval/run/keep the code?
No, it's the same interpreter and the queue could even be implemented in JavaScript. But the variables behind it are hidden away from the caller.
how can you access it in relation to the timeout uid?
The timeout ID is by design completely opaque. The only defined interface that can do anything with it is the clearTimeout/clearInterval call. There is no interface provided to get the function back from a timeout ID.

Categories