d3 svg symbol syntax [duplicate] - javascript

I noticed a difference when calling a function with empty parentheses, or without any parentheses at all. However, I am not passing any arguments to the function so I wondered, what would be the difference between:
window.onload = initAll();
and
window.onload = initAll;
Please explain the principle behind it.

window.onload = initAll();
This executes initAll() straight away and assigns the function's return value to window.onload. This is usually not what you want. initAll() would have to return a function for this to make sense.
window.onload = initAll;
this assigns the actual function to window.onload - this is possible because in JavaScript, as #Felix says, functions are first class objects - without executing it. initAll will be executed by the load event.
You may also see something like this:
window.onload = () => initAll();
This will create a new function that, when called, will call initAll immediately. Parentheses are necessary here for that "call initAll immediately" part to work. But, because it's wrapped in a function, nothing will execute until that outer function itself is called, and you assign the reference of that outer function to window.onload, so initAll will also be executed on the load event.

What Pekka says is correct, but I want to elaborate a little with an example that will help explain to someone who doesn't fully understand function pointers or delegates.
I won't use window.onload because that's a bit contrived to demonstrate. I'll use a simple multiply function to demo instead:
function Multiply(operator, operand) {
return operator * operand;
}
This could equally be written:
Multiply = function(operator, operand) {
return operator * operand;
}
While in the first example, the implication may not be obvious, the second example shows more clearly that we're assigning a function which has 2 parameters to a variable called Multiply, and this concept of functions as assignments is common throughout JavaScript. This is a small demonstration of the fact that functions are "first class citizens", that is, they can be passed around exactly as if we were passing around values.
So now to the difference of assignment:
var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);
At the point of defining the ret variable, Multiply is executed and the return value is assigned - ret becomes equal to 12.
Let's try that again a different way:
var operator = 3;
var operand = 4;
var ret = Multiply;
Now, at the point of defining ret, ret becomes your Multiply function as opposed to being the result obtained from your Multiply function. Calls to ret() will cause your Multiply function to be executed, and you can call it exactly as if you'd called Multiply(operator, operand):
var out = ret(3, 4);
is the same as
var out = Multiply(3, 4);
You have effectively said that you are going to use ret as a delegate for Multiply(). When calling ret, we're really referring to the Multiply function.
Back to your window.onload. Think of this as:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
initAll = function() {
return 12;
}
So as you can see, window.onload is a function just like any other function, there's nothing special about it. You can assign it a value, assign it a function, null it out if you wish - the point is that there's nothing any more special about window.onload than there is about your own function. The only slightly different thing is that it gets called by the window when it's loaded. [Disclaimer: I've never actually nulled out window functions, so I'm not sure if this will cause negative repercussions. One would hope they check to see if a function is assigned before calling it i.e. if (window.onload) window.onload();].
Now calling initAll() what we're saying is:
window.onload = initAll();
which might as well say:
window.onload = 12;
But when we say initAll without the parentheses, what we're really saying is: I want to replace whatever my window.onload function is, with a new function - i.e. I want to replace it with my initAll function, so that any calls to window.onload runs my initAll code.
So:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
is replaced with:
window.onload = function() {
return 12;
}
So any call to window.onload will execute your initAll function instead of whatever window.onload was originally. You have replaced the original function with your new function.
In fact, you could equally write:
window.onload = function() {
//Write all your init code right in here instead of having a separate
//initAll function.
}
Another example that may demonstrate better is this:
var d = new Date();
var currentTime = d.getTime();
Whatever the time was at the time d is defined ends up assigned to currentTime. Great, but that's only useful if we want to find out what time the function containing that code was called - i.e. at page load time. What if we want the current time any time that currentTime is called?
var currentTime = function() {
var d = new Date();
return d.getTime();
}
var a = currentTime(); //The current time at the point a is defined...
var b = currentTime; //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined
Notice how we call b() in our c and d assignments exactly as we could call currentTime()?

Functions in javascript are first-class citizens, and as such, can be assigned to other variables or passed around as arguments.
So, when you do
window.onload = initAll;
You are setting the onload property of the window object to reference the initAll function itself.
When you do
window.onload = initAll();
You are setting the onload property to hold the return value of initAll, since it will execute in place on that line.

I'm 6 years late but I feel this could have been explained a lot simpler than the above answers.
So here is the TLDR; or bird's eye view when calling functions using and not using ()'s
Lets take this function for example:
function foo(){
return 123;
}
if you log "foo" - without ()
console.log(foo);
---outout------
function foo(){
return 123;
}
Using no () means to fetch the function itself. You would do this if you want it to be passed along as a callback.
if you log "foo()" - with ()
console.log(foo());
-----output-----
123
Using () after a function means to execute the function and return it's value.

initAll is a reference to a function value and the brackets operator appended to the function name RUNS this function object.
So if you do something like
a = initAll
then a will become the same as initAll - for example you can do a() - but with
a = initAll()
the variable a will get the return value of the executed initAll function

Related

whats the difference between closures and this

I am just getting more into javascript and wandering what is the difference between
var myfunc = function(){
publicfunctions = {}
publicfunctions.function1 = function(){do smthing and return}
return publicfunctions
}
and
var myfunc = function(){
this.function1 = function(){do smthing and return}
}
It seems to me that both doing the same thing
Also can someone explain what is difference between
var func = (function myfunc(){ .. do smthing and return .. })();
and
var func = function myfunc(){ .. do smthing and return .. }
var newfunc = new myfunc()
Thanks
Let's go step by step.
example:
a) you define a function that returns an object (careful with variable declaration - you should declare it with var keyword in order to scope it to your function. That objects has a single property that points to a function. Never the less, your first function is assigned to a variable myfunc
Now, if you try to call myfunc(), you'll get an object with single property function1. Nothing special here.
b) you define a function again and assign it to myfunc variable, only this time it contains this keyword which assumes you're trying to utilize this function as a constructor. In this example, merely calling myfunc produce no output since you haven't returned anything from a function. However, calling a function with preceding keyword new will result in object creation.
var myObj = new myfunc();
// `this` keyword now refers to myObj which means myObj can call `function1`
example:
a) On the righthand side is something that is called IIFE (or Immediately Invoked Function Expression). Basically means, a function expression that is created and executed, well, immediately. So func should receive whatever that function returns.
b) Yet again, facing a constructor, only this time you actually assumed myfunc is a constructor when you added new keyword before myfunc execution. Creates an object to whic newfunc now points to and has authority over.
Note:
In constructor functions (the ones that you call with new keyword), this is implicitly returned and no need for explicit return. Now, if you want to test it and return something else instead, I'll leave it up to you to explore and see what you'll end up with. :)
Since it's a broader topic in itself, I recommend this excellent book by Nicholas Zakas. It really answers a lot of JS questions.

Doing Math in Multiple Javascript Functions

I'm new to the Javascript world and trying to figure out this assignment my teacher assigned. Here is his description of what is expected:
Build a function that will start the program. Please call it start()
From the start() function, call a function called getValue()
The getValue() function will get a number from the user that will be squared.
Also from the start function, call a function called makeSquare()
The makeSquare() function will square the number that was received by the user in the getValue() function.
Make sure that you display the results of squaring the number inside of the makeSquare() function.
Here is what I have so far:
function start() {
getValue();
getSquare();
}
function getValue() {
var a = prompt("Number please")
}
function getSquare() {
var b = Math.pow(a)
document.write(b)
}
start()
This assignment doesn't have to be working with any HTML tags. I've only got the prompt box to work, nothing else does though. Am I using variables in a way that can't be used?
You were close. But it seems that you don't understand scoping and how exactly to use the pow function.
Math.pow:
Math.pow takes two parameters, the base and the exponent. In your example, you only provide the base. That will cause problems as the function will return the value undefined and set it to b. This is how it should have looked (if you wanted to square it):
Math.pow(a, 2);
Scoping:
Every function has it's own scope. You can access other variables and functions created outside the function from within the function. But you cannot access functions and variables created inside another function. Take the following example:
var c = 5;
function foo() { // we have our own scope
var a = c; // Okay
}
var b = a; // NOT okay. a is gone after the function exits.
We could say that a function is private. The only exception is that we can return a value from a function. We return values using the return keyword. The expression next to it is the return-value of the function:
function foo() {
return 5;
}
var a = foo(); // a === 5
foo() not only calls the function, but returns its return-value. A function with no return-value specified has a return value of undefined. Anyway, in your example you do this:
function getValue() {
var a = prompt("Number please")
}
and access it like this:
// ...
var b = Math.pow(a)
Do you see the error now? a is defined in the function, so it can't be accessed outside of it.
This should be the revised code (Note: always use semicolons. I included them in for you where necessary):
function start() {
getSquare();
}
function getValue() {
var a = prompt("Number please");
return a;
}
function getSquare() {
var b = Math.pow(getValue(), 2); // getValue() -> a -> prompt(...)
document.write(b);
}
start();
As this is an homerwork, I won't give you direct answer, but here's some clue.
In javascript variables are functions scoped. That mean that var a inside getValue is only available in there.
You can return a value from a function.
Functions are first class object in javascript, so you can pass them as parameter to other function and finally call them inside that function.
Am I using variables in a way that can't be used?
Yes, that's where your problem lies. Variables in most programming languages have a scope that determines where they're available. In your case, a and b are local variables of the functions getValue() and makeSquare() respectively. This means they're not available outside the function they're declared in.
Generally speaking, this is a good thing. You should use restricted scopes for your variables to make the "flow" of data through your program clearer. Use return values and parameters to pass data between functions instead of making your variables global:
function start() {
var a = getValue();
makeSquare(a);
}
// Return a value entered by the user
function getValue() {
return prompt("Number please")
}
// Write the square of the `a` parameter into the document
function makeSquare(a) {
var b = Math.pow(a)
document.write(b)
}
Your getValue() needs to return the value, so that you then can pass it to the getSquare() function.
In my opinion, you should always end each line with ;
You will probably need to parse the user input into a number. For that you can use parseFloat(string).
Math.pow takes two arguments, so to get the square, you would have to pass 2 as a second argument when calling it.
I edited your code with some clarifying comments:
function start() {
// Catch the value returned by the function
var value = getValue();
// Pass the returned value to the square-function
getSquare(value);
}
function getValue() {
// Parse the user input into a number, and return it
return parseFloat(prompt("Number please"));
}
// Let the square-function take the user input as an argument
function getSquare(a) {
// Math.pow takes a second argument, which is a number that specifies a power
var b = Math.pow(a, 2);
document.write(b);
}
start();
Another, less good way
In JavaScript, variable-scoping is based on functions. If a variable is declared using the var keyword, it is only available to that function, and its child-functions. If it is declared without the var keyword, or declared outside any function, it becomes a global variable, which will be accessible by any code run on that page.
That said, you could get rid of the var keyword inside the getValue() function, which would make the variable a global. You could then access it from within getSquare() the way you tried in your example.
This is generally not a good idea though, since you would "pollute" the global namespace, and you would be running the risk that you accidentally have another script using a global variable with the same name, which would cause all kinds of trouble, when the scripts start to work with the same variable.
You can try this.
<script type="type/javascript">
function start(){
makeSquare(getvalue());
}
function getvalue(){
return prompt("enter a number");
}
function makeSquare(a){
var result=Math.pow(a,2);
alert(result);
}
start();
</script>

Is function declaration without the "function myFunction() {}" syntax discouraged in javascript? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
There are two ways to declare a function in Javascript:
Syntax 1:
function myFunction() {
// something awesome
};
Syntax 2:
var myFunction = function() {
// somtehing even more awesomer
};
It seems to me that I come across Syntax 1 a lot more in legacy code than in well written code (but that's purely empiric).
Q: Should prever a syntax over the other, and why ?
The only difference that I can think of is here:
This code does not run: http://jsfiddle.net/JdCRq/
myFunction();
var myFunction = function() {
console.log('test');
};
While this code does: http://jsfiddle.net/JdCRq/1/
myFunction();
function myFunction() {
console.log('test');
}
function blocks, in the context of the second example, seem to be declared (at least by name) before the code is actually run.
The first example is the normal way of declaring a function.
The second example is an anonymous function that is assigned to a variable. This is used when you declare a function as a member of an object, or assign it to the prototype of a class, and is sometimes also used when assigned to a regular variable when the normal way of declaring a function would suffice.
The only practical difference between the examples is that the second way is assigned at runtime. If you redefine a function, that happens when the code is parsed, so only the last one exists:
console.log(f()); // shows 2
function f() { return 1; }
console.log(f()); // shows 2
function f() { return 2; }
console.log(f()); // shows 2
(Although you normally wouldn't redefine a function like that, because it makes the code hard to follow.)
With an anonymous function, it doesn't exist until it is assigned, and if reassigned it changes to the new function:
condole.log(f); // shows undefined
var f = function(){ return 1 };
console.log(f()); // shows 1
f = function(){ return 2 };
console.log(f)); // shows 2
Declaring a function with the function declaration statement (the first way) binds the function name to the function object in such a way as to allow debuggers to show you the name in stack traces. There's really no reason to declare functions with var declarations in simple cases like this. (Sometimes, of course, it's necessary, as when you create functions with other functions.)
Syntactically, it's OK for function instantiation expressions (the second way) to also include a function name that's bound to the function. Unfortunately, some JavaScript runtimes don't handle that case properly and behave somewhat badly, so it's not a good idea.
Using both var and function can have some advantages depending on what you want to achieve, here are some examples;
var f1 = function nonUnique () {return true;},
f2 = function nonUnique () {return false;};
meaning f1.name === f2.name but f1 !== f2
function nonUnique () {return true;};
var f1 = nonUnique;
function nonUnique () {return false;}; // this line changes f1 too
var f2 = nonUnique;
means f1 === f2 and f1 will now return false.
function nonUnique () {return true;};
var f1 = nonUnique,
f2 = f1;
f1 = function nonUnique () {return false;}; // this line changes f1 but not f2
means f1 !== f2; f1 returns false but f2 will return true. nonUnique() will also give true.
This last example is useful of re-using native functions names but keeping them safe.
Also note that variables effectively don't exist before the line with var whereas function syntax will, and see this question, which your question is a duplicate of.

Why doesn't this extension work?

I wanted to have a method of adding functionality to pre-existing functions, so I made this:
Function.prototype.attachFunction = function(toAttach)
{
var func = this; //This is the original function, which I want to attack toAttach function to.
//Can I do this without wrapping it in a self-executing function? What's the difference?
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
I paste this into the Google Chrome console, and there are no errors, however, it does not (or so it would seem) alter the original function at all.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f(); //Prints out just "g".
When attachFunction executes, it returns a function which executes func() and toAttach. However, if you change your code to be the following, it will attempt to execute both functions, where currently the old f is still called at the end.
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f(); //Causes an infinite loop since calling func() is the same as calling this()
To merge two functions we need to wrap them the same way but not while extending Function
var func1 = function(){
console.log('g');
};
var func2 = function(){
console.log('New function!');
};
func1 = (function(f1,f2){
return function(){
f1();
f2();
}
}(func1, func2));
func1(); //Writes out both g and New function!​​​​​​​​​​​​​​​​​​​​
The reason I pass in func1, and func2 as parameters is to prevent the same problem of getting into an infinite loop. I want to maintain a reference to these functions at that point in time.
A helper function would then be the following
function combineFunctions(f1, f2){
return function(){
f1();
f2();
}
}
and would be used like this
var f = function() {console.log("g");};
f = combineFunctions(f,function(){console.log("New function!");});
f();
The attachFunction method you've set on the Function prototype is a higher-order function, or combinator, that accepts a function and returns a new function. It is inherited by any function created thereafter, as expected. However, when it is called it does not alter the state of f in any way, it simply produces a new function that calls f, or the calling function rather.
So, if you wanted to see both console.log messages, you simple need to call the function it returns, like so:
f.attachFunction(function(){console.log("hi")})();
or more simply:
f.attachFunction(f)();
Note that although functions are objects, the execution context (code) of f is not a property of f such that it can be manipulated directly, it is kept in an internal attribute.
Underscore.js' wrap() function should be quite close to what you want.
Currently, you're trying to call a variable as if it were a function (toAttach is a variable and you're smacking some parenthesis on the far side of it). Consider this: toAttach may CONTAIN a function, but that does not make it a function (much like a grocery store is not an apple). Instead you need to call the function contained within the variable.
There are several ways to do this (although only one or two apply here), none of the [right] ways involve eval() (life lessons).
Consider this thread. Pass the function name as a string and then use
window[toAttach]();
to call the function. It's a bit hacky, and lacks the finesse of passing the function as an object, but it works.
Alternatively (completely depending on your needs) you can bind the function to an event. If you're extra sneaky (and why not?) you can use
setTimeout(toAttach, 0);
Where toAttach is a reference to the actual function (again).
Finally, and best, I believe, is the Function.call() method. Using this, you can call a function stuffed in a variable, and even pass it a context for this.
toAttach.call([Context]);
Where [Context] is the context of the function (ie, what this refers to when inside of the function, in most cases it can be left blank to get the desired scope). I can't say I've tested it under your certain circumstances (thus why I have included it last), but I believe it should give you the results you're looking for.
Here's my attempt to achieve this, it is not clean as if it was entirely in the prototype but it works. There are probably better ways than mine.
var bindings={};
function execBindings(func_name) {
if (bindings[func_name] != undefined) {
for (var i=0;i<bindings[func_name].length;i++) {
bindings[func_name][i]();
}
}
}
Function.prototype.bind=function(action){
if (bindings[this.name] == undefined) {
bindings[this.name]=[];
}
bindings[this.name].push(action);
}
Then, to use the binding :
function f() {
alert("foo");
execBindings("f");
}
f.bind(function(){
alert("bar");
});
f.bind(function(){
alert("test");
});
f();
which results in 3 alerts, in the order thwy were binded to the function.
There are two problems I just found.
problem 1.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f();
It definitely doesn't work, cause attachFunction just wrap around your original function and return the wrapped, it doesn't change the original function, which means your f function is still f = function() {console.log("g");}
Problem 2.
If you reassign f with the result of attachFunction, an Maximum call stack size exceeded will occur. In the definition of attachFunction:
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func;
The func function call himself recursively.
Update
I prefer this approach.
Function.prototype.attachFunction = function(toAttach)
{
var that = this;
func = (function()
{
return function()
{
that();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f();

Function doesn't run when calling it with added parenthesis (even though it doesn't need parameters)

Here's my function to alert me of the number of childNodes of the body tag.
function countBodyChildren() {
var body_element = document.getElementsByTagName("body")[0];
alert(body_element.childNodes.length);
}
window.onload = countBodyChildren;
The function runs fine, but when I add () to the end of the function name i.e. window.onload = countBodyChildren(); the function does not run. Why is this? I thought to call functions, even if they don't need any parameters, you always add the () to the end of its name.
I thought to call functions, even if they don't need any parameters, you always add the () to the end of its name.
You thought correctly. But here, you don't want to call the function; you want to tell the browser which function to call when the time comes.
When you add the parentheses, you will call the function, immediately (not on load). The function executes; tries to look up the body elements, but there is none loaded yet; so you body_element ends up as undefined. You look up childNodes on undefined, and get an error. window.onload assignment does not happen.
Even if your function did not throw an error, it would have returned undefined, so window.onload becomes undefined, so nothing happens when the page is finally loaded.
Instead, you need to start thinking that functions are just another kind of value. When you say
function a() {
// ...
}
it is the same as this:
a = function() {
// ...
};
(Actually there are differences, important ones, but they're irrelevant for now; look them up when you have the basics down pat). A function is now "contained" in variable a. Then you can do this:
var b = a;
b();
and it will work - you're putting whatever was in a (your function) into the variable b, and then executing it by invoking its new name (since now both a and b refer to the same function). In the same way, after
window.onload = countBodyChildren;
the onload property of the window object now contains your function. Browser will then execute whatever is there when the load finishes.
You had a case of premature execution.
What window.onload expects is a reference to a function or a function definition.
When you put parenthesis, you actually execute the function and it is the return value of the function that is assigned to window.onload.
window.onload = countBodyChildren();
That says "call the function, and assign the return value of the function to the onload property of the window object. Your function returns nothing.
For example
function countBodyChildren() {
var body_element = document.getElementsByTagName("body")[0];
alert(body_element.childNodes.length);
return 5;
}
window.onload = countBodyChildren();
that would assign 5 to the onload prop. Not what you want. you need to assign a function reference to the onload prop, so the js engine can call the function when the event occurs.

Categories