Understanding JavaScript function declaration syntax [duplicate] - javascript

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
After using JavaScript for a while, I came up with some questions.
The way to declare a function is:
var myFunction = function(param){//code here}
But there is also another way to declare a function which is
function myFunction(param){//some code}
What's the difference between the two methods to declare a function?
My second question is, I've understood that you can create an object from a function that's declared as:
function Person(name){this.name=name;}
And then, you can have another function declared like this:
function Speak(){console.log(this.name);}
How does the function Speak knows that it's related to the Person Object?

The first one is expression
var myFunction = function(param){//code here}
Second is declaration
function myFunction(param){//some code}
see this article
http://kangax.github.io/nfe/

When u use the word var, your'e declaring a variable realtive to where it's defined, and cannot be accesed from out wheres, and if its inside a function, it's destroyed at the end of the execution, and if you dont use it, you're defining on global ambit, and the variable still exists after the function execution.
The second thing is for programming OOP
Yo can use functions as same as it they were pure objects:
var person = {
name: null,
setName: function (name) {
this.name = name
}
}
Then you can access it's property
person.setName('john');
console.log(person.name);
in the shape of a function
function Person(name){
this.name = null;
}
var john = new Person('John');
console.log(john.name);

When you use this syntax:
function f1(){}
then f1 can be used everywhere in the current scope:
// we can call f1 even before definition of the function
f1(); // it works
function f1(){}
But, When we use this syntax:
var f1 = function(){};
then f1 is like as a pointer to an anonymous function which can be used after the point of assignment:
// we can't call it before assignment of our var
//f1(); // f1 is undefined here!
var f1 = function(){}
// we can call it here
f1(); // works
The second syntax is make more sense when you consider that every function is also an object. for example, we can have a function be a property of an object, like this:
var myObject = new Object();
myObject.say = function(x) {alert(x);};
// myObject now has a property/method named "say"
myObject.say("Hello");
About the second question: the this keyword. can you give the (outer) scope of your code which defines your Person and Speak functions? the code you wrote won't work as it is written. If you want to set proper reference for this in Speak function, you have to write something such as below:
function Person(name){ this.name=name; }
function Speak(){ alert(this.name); }
Person.prototype.DoSpeak = Speak; //here we attach DoSpeak to Speak function
var p = new Person("Saeed");
p.DoSpeak(); //this will work

Both are declaration
1) var myFunction = function(param){//code here}
This is a declaration that is assigned to 'myFunction' local variable
You can set an identifier for that function for debug or recursion purposes
var myFunction = function myFunctionIdentifier(param){ console.log(myFunctionIdentifier.toString())}
But to call this function you have to use 'myFunction ' variable
Another way to perform nested call is by using the arguments.callee that points to the function itself
var myFunction = function(param){ console.log(arguments.callee.toString())}
2) function myFunction(param){//some code}
This is a declaration that is assigned to the scope variable
in case you are in the global area it will be assign (for example in the browser) to the window object
So in fact window["myFunction"]() is valid
* About this question...
function Person(name){this.name=name;}
function Speak(){console.log(this.name);}
The reason that Speak 'knows' Person name is all about JavaScript scope.
Since both using the same scope, both functions 'speak' with the same this.
For example: if you code both functions in the global scope, this == window object thus
console.log(window['name']); will give you the name.
You don't want to code in that way .. since another function using this.name will override you existing logic.
If you will instantiate the Person entity
var person = new Person();
Then person variable will be this, this == person object
And the you can assign Speak in two or more ways:
inline:
function Person() {
...
this.Speak = function ...
}
outside the code, since person assign to (Person)this
person.Speak = function() ...
or the best way, use the prototype object:
Person.prototype.Speak = function() ...

Related

Can someone explain working of this js code with reference to 'this' keyword?

JS code is:
this.sound1 ="global";
function cat(){
this.sound = 'meawo!!!!';
this.sound1 = 'meawooooo!!!!';
meawo1 = function(){
console.log(this.sound1);
console.log(this);
};
function meawo2(){
console.log(this.sound1);
console.log(this);
};
this.meawo = function(){
console.log(this.sound);
console.log(this);
meawo1();
meawo2();
};
};
var c = new cat();
c.meawo();
Output is:
Question: How come this inside of meawo1(function expression) & meawo2(function expression declaration) is referring to "global" and not to object c? Why is that?
Always remember a simple tip while wanting to know to which object does this refer to.
obj.method();
In the above, method's is called on obj, and hence the this in method will be what it's called on, i.e obj = this.
In your case, though meowo is called on c, meowo1 and meowo2 aren't on the object you want it to refer to.
Functions which don't have an explicit scope from which they are called, default to global context, though the function itself isn't global and can leverage all the variables in its parent context due to a closure.

Javascript function and this [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 8 years ago.
I am learning javascript but I have some doubts about functions/closures, i have this code:
var obj = { value: 0 };
obj.test = function() {
var that = this;
var f1 = function() {
console.log(that);
};
f1();
};
obj.test();
var x = obj.test;
x();
I know that when a function is invoked like f() this refer to the global object but in my example when f1 is defined it has a reference that to the this of the outer function that refer to obj.
I expect that the function remember the context in which it was created so why the last call x() refers to the global object?
Thanks
I expect that the function remember the context in which it was created
That right there is your mistake. JavaScript functions do not "remember" any relationship to any particular object in a case like that. The only things they remember are in-scope variables in the chain of parent lexical contexts. In this case, the "obj" variable is such a variable.
You can explicitly create a function that remembers a relationship to an object with the .bind() method.
obj.boundTest = obj.test.bind(obj);
var x = obj.boundTest;
x(); // will do the right thing
or even more simply:
var x = obj.test.bind(obj);
x();
I expect that the function remember the context in which it was created
It doesn't.
Context is determined by how a function is called and only by how a function is called.
You are calling it in the global context, so this is the global object.
The reason for this occurring is that when you make a copy of that function
var x = obj.test;
you are only copying the function. Not the object, nor any of its variables. So when you attempt to run x (which is obj.test) it runs fresh. The result is that this is re-evaluated which now refers to the global context (or undefined in strict mode).

JavaScript function members differences

I'm still confused about this part of the closure although I read about it a lot (also here in the site).
Took the code from here:
http://www.crockford.com/javascript/private.html
So what is the different between this:
function Container(param) {
this.member = param;
}
...And this -
function Container(param) {
var member = param;
// and also in case it's without "var", I.e. global
}
Please explain what happens when you're creating the obj for each case -
var myContainer = new Container('abc');
Also -
What are the access differences for the parameter from the object? And can you give example for a function as a parameter and a returning function?
Thanks a lot!
Here is my opinion:
When you use the new to create an object through function,the variable initial by var is local variable:
function Test(){
var name = "John";
this.getName = function(){
return name;
}
}
var obj1 = new Test();
console.log(obj1.name); //undefined
console.log(obj1.getName()); //John
That means you can't read the variable directly outside the function.This is like private variable in Java or c++;
but when you use this.name = "John", this is a different situation:
function Test2(){
this.name = "John";
}
var obj2 = new Test2();
console.log(obj2.name) //"John"
you can read the variable directly, this is like "public" variable in java or c++.
Hope this can work for you. : )
In function Test, when we declare a variable obj1 with new Test. It have been created through the contructor function which is called "Test".
This process is like we call a function in a normal way. Of course that make a local variable "name". When we decleared a function expression which is called "this.getName", that just mean an expression to function "Test".
But when we call the "new Test".It return a object which have a key-value call "getName:function{}". When we call "obj1.getName", it return the variable "name". But it cannot find the getName's local variable "name", so it will search its parent's scope to find if there is a variable "name",it will not stop until we get it or just return "undefined". That make an "quote" to keep the variable "name" in memory, but we just can get it through the function "getName".
For all of this, we make a private variable in our function "Test". : ) Hope this can help.

Javascript: why "this" inside the private function refers to the global scope?

Consider the following code:
function A() {}
A.prototype.go = function() {
console.log(this); //A { go=function()}
var f = function() {
console.log(this); //Window
};
f();
}
var a = new A();
a.go();
Why does 'this' inside function 'f' refers to the global scope? Why it is not the scope of function 'A' ?
JavaScript has a different concept of what the special name this refers to
than most other programming languages do. There are exactly five different
ways in which the value of this can be bound in the language.
The Global Scope
this;
When using this in global scope, it will simply refer to the global object.
Calling a Function
foo();
Here, this will again refer to the global object.
ES5 Note: In strict mode, the global case no longer exists.
this will instead have the value of undefined in that case.
Calling a Method
test.foo();
In this example, this will refer to test.
Calling a Constructor
new foo();
A function call that is preceded by the new keyword acts as
a constructor. Inside the function, this will refer
to a newly created Object.
Explicit Setting of this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // array will expand to the below
foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3
When using the call or apply methods of Function.prototype, the value of
this inside the called function gets explicitly set to the first argument
of the corresponding function call.
As a result, in the above example the method case does not apply, and this
inside of foo will be set to bar.
Note: this cannot be used to refer to the object inside of an Object
literal. So var obj = {me: this} will not result in me referring to
obj, since this only gets bound by one of the five listed cases.
Common Pitfalls
While most of these cases make sense, the first one is to be considered another
mis-design of the language because it never has any practical use.
Foo.method = function() {
function test() {
// this is set to the global object
}
test();
}
A common misconception is that this inside of test refers to Foo; while in
fact, it does not.
In order to gain access to Foo from within test, it is necessary to create a
local variable inside of method which refers to Foo.
Foo.method = function() {
var that = this;
function test() {
// Use that instead of this here
}
test();
}
that is just a normal variable name, but it is commonly used for the reference to an
outer this. In combination with closures, it can also
be used to pass this values around.
Assigning Methods
Another thing that does not work in JavaScript is function aliasing, which is
assigning a method to a variable.
var test = someObject.methodTest;
test();
Due to the first case, test now acts like a plain function call; therefore,
this inside it will no longer refer to someObject.
While the late binding of this might seem like a bad idea at first, in
fact, it is what makes prototypal inheritance work.
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
When method gets called on a instance of Bar, this will now refer to that
very instance.
Disclaimer: Shamelessy stolen from my own resources at http://bonsaiden.github.com/JavaScript-Garden/#function.this
The reason why is you are invoking f as a function and not a method. When invoked as a function this is set to window during the execution of the target
// Method invocation. Invoking a member (go) of an object (a). Hence
// inside "go" this === a
a.go();
// Function invocation. Invoking a function directly and not as a member
// of an object. Hence inside "f" this === window
f();
// Function invocation.
var example = a.go;
example();
The scope of all functions is window.
To circumvent that, you can do this:
function A() {}
A.prototype.go = function() {
var self = this;
console.log(self); //A { go=function()}
var f = function() {
console.log(self); //A { go=function()}
};
f();
}
Because function f() is not called without any object reference. Try,
f.apply(this);

What is the difference between declaring javascript objects with var vs. with function?

I'm a confused newbie. I read in a tutorial that you create a javascript object like so:
function myObject() {
this.myProperty = "a string";
this.myMethod = function () {
//Method code
}
}
Then I read somewhere else that you create an object like so:
var myObject = {
myProperty: "a string",
myMethod : function () {
//Method code
}
}
What is the (non-subjective) difference between the two? Is there an official right way and a wrong way?
Both declarations are correct but they have different semantics.
The first type of declaration allows you to create instances of your objects:
var t = new myObject();
// then use t
t.myProperty = "some value";
var otherT = new myObject();
otherT.myProperty = "some other value";
The second is almost like a static object:
myObject.myProperty = "some value";
Here is a direct comparison...
function myObject() {
This declares the function when JavaScript is parsed...
var myObject = function () {
This declares the function at run time.
If you use the "var" method, your function must be declared before you use it... try this example.
myFunction(); // Works
myVarFunction(); // Boom
var myVarFunction = function () { alert("Hi"); };
function myFunction() { alert("Hi"); };
So why use the "var" method if you have to be more careful to use it? It is all to do with the scope... scoped functions are considered better.
UPDATE: And there are some great explanations here:
var functionName = function() {} vs function functionName() {}
The major difference between the two is that one variable is local and the other is global. “var” basically defines the scope of the variable.
When we add var to a variable value assignment, javascript ensures that the variable is confined to whichever function it is assigned to and does not collide with the same name variable within another function.
When we don’t use var, then it is declared as a global function and chances of collision can happen. So it’s always advisable to use “var” before variable value assignment. If needed use an anonymous function for closure.

Categories

Resources