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) {}
Related
I've seen others using the following pattern.
var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined
But why? I can see the point if both were declared, but they're not. Why is the reason?
As mentioned by others, using the first form in your example (a named function expression) can help with debugging, although with the recent improvements in built-in developer tools in browsers, this argument is becoming less persuasive. The other reason for using a named function expression is that you can use the function name as a variable within the body of the function rather than the now-deprecated in ES5 arguments.callee.
However, named function expressions are incorrectly and problematically implemented in Internet Explorer < 9 and should generally be avoided when you're targeting those browsers. See Juriy Zaytsev's excellent article on the subject for more information.
When debugging an application, it is easier to know what is calling what in the call stack when "named" anonymous functions are used. So it is a way to give a name to an anonymous function for debugging purposes.
Try this and look at the callstack in a debugger:
myDiv = document.getElementById("myDiv");
myDiv.onclick = function OnClick(){
debugger;
//do something
}
They are naming an anonymous function because it makes debugging easier. When debugging, you will see a call to "foo" in the call stack rather than a bunch of calls to "anonymous".
The only reason I can imagine for this is to give the function a desired name. This helps debugging as the inspector uses the function object's name attribute. Try this:
var bar = function foo(){};
console.log(bar.name); // foo
If you put some real code inside foo and add a breakpoint to the JavaScript debugger in your browser, you will see the function as foo in the call stack.
The function definition (or literal) has 4 parts. 1. The reserved word function 2. An optional name which can be used by debuggers or by the function to call itself recursively. 3. The parameters and 4. The body of the function wrapped by { }
Outside of the function scope foo doesn't exist. But since you assigned the function to the variable bar you can call it using the method invocation bar and since bar is defined you can print it.
If you're interested in JavaScript you should really consider getting Douglas Crockford's book Javascript: The Good Parts
I had a question when reading a source code. The code example is as below:
// ... some code omitted
function p() {var u=new i();this. $Arbiter0=new s(); this.$Arbiter3=[];}
p.prototype.subscribe = function() { ... }
p.call(p) // <-- what is the purpose of this statement?
I'm new at JavaScript. I read from textbook that, when you use Function.call(Function), it usually means borrow inganother function constructor, in order to do some code-reuse/inherit stuff. BUT, I'm not sure what the purpose of doing it in this code example, i mean, the function is calling the function itself?
Clarify:
I know the use of Function.call(). I just want to know, what is the benefit of doing foobar.call(foobar)?
====
The complete source code is as below:
https://fbstatic-a.akamaihd.net/rsrc.php/v2/y6/r/USEL5meM70H.js
Search 'p.call(p)' in that source code. There is only one occurrence in that file.
====
Thank you.
p.call(p) has the effect of calling the function p, such that the value of this, within the function body, is the function itself.
This allows you to add properties to the function from within the function.
Relevant documentation for Function.call can be found here.
Since this is minified code, it's possible that this construct is an artifact of the minification process. It seems that the intent here is to initialize p; it's probably setting up data structures for storing subscribers.
The first argument for the .call is the element that will be used as this in the executed function.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
You know in JavaScript, functions are also Objects. That means you can have method and properties associated to functions.
For example :
I can create a function called foo and add a property to it like below
function Foo(){};
Foo.bar = [1,2,3,4,5];
Foo.sayName = function(){ alert("hi Tom")};
This methods are called as static methods ( Classical OOP pattern: function constructor act like a class in javascript ), so that you don't need to instantiate an Object of Foo to access sayName method.
Coming back to the actual question. What happens when you do Foo.call(Foo);
The call method expect an object as the first parameter, and invoke the function on which it's called. When the function is invoked, this pointer will be pointed to the object passed. In this case, it's the Foo function ( Object ) itself.
Assume that if Foo function is written this way
function Foo(){
this.bar = [1,2,3,4,5];
this.sayName = function(){ alert("hi")};
}
After executing Foo.call(Foo), you can see that the actual Foo function ( Object ) will have the properties bar and method sayName got added.
I guess the script which you have sent is doing that to reduce code duplication.
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.
I study JavaScript Proxy Pattern, but I still do not get, where I can benefit from it. I would therefore like to provide you with two examples and kindly ask you to point at the difference between them.
Please, take a look at the code below:
What is the difference between the two addEventListener calls? One of them calls handleDrop in regular way. The other uses Proxy Pattern.
What will I gain using Proxy pattern approach?
I tested both functions, and they both call handleDrop successfully.
DndUpload.prototype.buildDropZone = function ()
{
var self = this,
this.dropZone.addEventListener('drop', function (e) { self.handleDrop.call(self, e) }, false);
this.dropZone.addEventListener('drop', self.handleDrop, false);
DndUpload.prototype.handleDrop = function (e)
{
alert("test");
...
};
}
You can provide me with good reference which contains very clear explanation of Proxy Pattern in JavaScript.
So what you're describing in your example isn't so much a demonstration of the Proxy pattern as much as a demonstration of confusion regarding the "calling object" and how it works in JavaScript.
In JavaScript, functions are "first-class." This essentially means that functions are data just like any other data. So let's consider the following situation:
var fn = (function () { return this.x; }),
a = {
x : 1,
fn : fn,
},
x = 2,
nothing = (function (z) { return z; });
So, we have an object a, which has two properties: fn and x. We also have variables x, fn (which is a function returning this.x), and nothing (which returns whatever it gets passed).
If we evaluate a.x, we get 1. If we evaluate x, we get 2. Pretty simple, eh? Now, if we evaluate nothing(a.x), then we get 1. That's also very simple. But it's important to realize that the value 1 associated with the property a.x is not in any way connected to the object a. It exists independently and can be passed around simply as a value.
In JavaScript, functions work the same way. Functions that are properties (often called "methods") can be passed as simple references. However, in doing so, they can become disconnected from their object. This becomes important when you use the this keyword inside a function.
The this keyword references the "calling object." That's the object that is associated with a function when that function is evaluated. There are three basic ways to set the calling object for a function:
If the function is called using the dot operator (e.g. a.fn()), the relevant object (in the example, a) is set as the calling object.
If the function is called using the function's call or apply properties, then you can explicitly set the calling object (we'll see why this is useful in a second).
If no calling object is set through method 1 or method 2, the global object is used (in a browser, this is typically called window).
So, back to our code. If we call a.fn(), it will evaluate as 1. That's expected because the this keyword in the function will be set to a due to the use of the dot operator. However, if we call simply fn(), it will return 2 because it is referencing the x property of the global object (meaning our global x is used).
Now, here's where things get tricky. What if you called: nothing(a.fn)()? You might be surprised that the result is 2. This is because passing a.fn into nothing() passes a reference to fn, but does not retain the calling object!
This is the same concept as what's going on in your coding example. If your function handleDrop were to use the this keyword, you would find it has a different value depending on which handler form you use. This is because in your second example, you're passing a reference to handleDrop, but as with our nothing(a.fn)() example, by the time it gets called, the calling object reference is lost.
So let's add something else to the puzzle:
var b = {
x : 3
};
You'll note that while b has an x property (and therefore satisfies the requirements for fn's use of this), it doesn't have a property referencing fn. So if we wanted to call the fn function with its this set to b, it might seem we need to add a new property to b. But instead we can use the aforementioned apply method on fn to explicitly set b as the calling object:
fn.apply(b); //is 3
This can be used to "permanently" bind a calling object to a function by creating a new function "wrapper." It's not really permanently binding, it's just creating a new function that calls the old function with the desired calling object. Such a tool is often written like so:
Function.prototype.bind = function (obj) {
var self = this;
return function() {
return self.apply(obj, arguments);
};
};
So after executing that code, we could do the following:
nothing(a.fn.bind(a))(); //is 1.
It's nothing tricky. In fact, the bind() property is built into ES5 and works pretty much like the simple code above. And our bind code is actually a really complicated way to do something that we can do more simply. Since a has fn as a property, we can use the dot operator to call it directly. We can skip all the confusing use of call and apply. We just need to make sure when the function gets called, it gets called using the dot operator. We can see how to do it above, but in practice, it's far simpler and more intuitive:
nothing(function () { return a.fn(); })(); //is 1
Once you have an understanding of how data references can be stored in closure scope, how functions are first-class objects, and how the calling object works, this all becomes very simple to understand and reasonably intuitive.
As for "proxies," those also exploit the same concepts to hook into functions. So, let's say that you wanted to count the number of times a.fn gets called. You can do that by inserting a proxy, like so (making use of some concepts from our bind code from above):
var numCalls = (function () {
var calls = 0, target = a.fn;
a.fn = (function () {
calls++;
return target.apply(a, arguments);
});
return (function () {
return calls;
});
}());
So now, whenever you call numCalls(), it will return the number of times a.fn() was called without actually modifying the functionality of a.fn! which is pretty cool. However, you must keep in mind that you did change the function referenced by a.fn, so looking way back to the beginning of our code, you'll notice that a.fn is no longer the same as fn and can't be used interchangeably anymore. But the reasons should now be pretty obvious!
I know that was basically a week of JavaScript education in a couple pages of text, but that's about as simple as it gets. Once you understand the concepts, the functionality, usefulness, and power of many JavaScript patterns become very simple to understand.
Hope that made things clearer!
UPDATE: Thanks to #pimvdb for pointing out my unnecessary use of [].slice.call(arguments, 0). I have removed it because it's, well, unnecessary.
Basically, passing self.handleDrop directly is functionally equivalent to passing the following function:
function() {
return self.handleDrop.apply(this, arguments);
}
because everything is passed through to the original function:
The this value
The arguments
The return value
With this in mind, compare your functions as follows:
function(e) { self.handleDrop.call(self, e) }
function() { return self.handleDrop.apply(this, arguments); }
The difference with your proxy way is:
It doesn't pass the return value through.
It doesn't pass all arguments through (only the first, e)
It doesn't pass the this value through, but uses a predefined one: self.
Now, the first two items don't make a difference here, because addEventListener doesn't care about the return value, and it also only passes one argument anyway.
But the third item is important: it sets a different this value in the function. By default, this is the element you bind the event to (it it set by the browser). Using the proxy way, you can set another this value.
Now, in your snippet it is not fully clear why you're setting a prototype function each time buildDropZone is called. Usually you define prototype functions only once. But when your handler handleDrop is called using the proxy way, this refers to the DndUpload instance, which is consistent with prototype functions in general.
Consider the code below:
function printThis() {
console.log(this);
}
var someObject = {
performTest : function() {
var self = this;
someOtherObject.higherOrderFunction(printThis);
someOtherObject.higherOrderFunction(function(){printThis.call(self)});
}
}
var someOtherObject = {
higherOrderFunction : function(f) {
f();
}
}
What will someOtherObject.higherOrderFunction(printThis) return?
How about someOtherObject.higherOrderFunction(function(){printThis.call(self)})
The answer to the first question depends on who and how you call someObject.performTest(). If I just call someObject.performTest() from a global context, it will probably print Window.
The second one will always print the someObject instance no matter what.
The closures or 'proxy pattern' as you call it comes in handy when you want to control exactly the execution context of a function.
Note: this in javascript does not behave like it does in other languages(in Java for example).
I've seen others using the following pattern.
var bar = function foo(){};
console.log(bar); // foo()
console.log(foo); // ReferenceError: foo is not defined
But why? I can see the point if both were declared, but they're not. Why is the reason?
As mentioned by others, using the first form in your example (a named function expression) can help with debugging, although with the recent improvements in built-in developer tools in browsers, this argument is becoming less persuasive. The other reason for using a named function expression is that you can use the function name as a variable within the body of the function rather than the now-deprecated in ES5 arguments.callee.
However, named function expressions are incorrectly and problematically implemented in Internet Explorer < 9 and should generally be avoided when you're targeting those browsers. See Juriy Zaytsev's excellent article on the subject for more information.
When debugging an application, it is easier to know what is calling what in the call stack when "named" anonymous functions are used. So it is a way to give a name to an anonymous function for debugging purposes.
Try this and look at the callstack in a debugger:
myDiv = document.getElementById("myDiv");
myDiv.onclick = function OnClick(){
debugger;
//do something
}
They are naming an anonymous function because it makes debugging easier. When debugging, you will see a call to "foo" in the call stack rather than a bunch of calls to "anonymous".
The only reason I can imagine for this is to give the function a desired name. This helps debugging as the inspector uses the function object's name attribute. Try this:
var bar = function foo(){};
console.log(bar.name); // foo
If you put some real code inside foo and add a breakpoint to the JavaScript debugger in your browser, you will see the function as foo in the call stack.
The function definition (or literal) has 4 parts. 1. The reserved word function 2. An optional name which can be used by debuggers or by the function to call itself recursively. 3. The parameters and 4. The body of the function wrapped by { }
Outside of the function scope foo doesn't exist. But since you assigned the function to the variable bar you can call it using the method invocation bar and since bar is defined you can print it.
If you're interested in JavaScript you should really consider getting Douglas Crockford's book Javascript: The Good Parts