3

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?

Colin Brock
  • 21,267
  • 9
  • 46
  • 61
kfirba
  • 5,231
  • 14
  • 41
  • 70
  • For the `this` keyword look here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – elclanrs Dec 22 '13 at 06:26
  • The answer to your second answer is when you create a new person with: `var ben = new Person("Ben");` then call speak setting the invoking object to ben: `speak.call(ben);` If speak is behaviour of a Person you should put it on Person.prototype: `Person.prototype.speak=function()...` you an then do `ben.speak();` More on constructor functions, prototype and invoking object here:http://stackoverflow.com/a/16063711/1641941 – HMR Dec 22 '13 at 08:39

4 Answers4

1

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/

Rick Li
  • 1,457
  • 2
  • 14
  • 19
  • Both are expressions. One simply binds the result of the expression to a lexically scoped variable. – David-SkyMesh Dec 22 '13 at 06:35
  • @David-SkyMesh—please don't confuse things. The answer is correct, ECMA-262 defines both [*FunctionDeclaration*](http://ecma-international.org/ecma-262/5.1/#sec-13) and [*FunctionExpression*](http://ecma-international.org/ecma-262/5.1/#sec-13) per the above answer. The first is a [variable statement](http://ecma-international.org/ecma-262/5.1/#sec-12.2) that combines a variable declaration and assignment of a function expression, also called an initialiser. – RobG Dec 22 '13 at 06:50
  • @RobG No doubt that's what the grammar productions are called. How are they different in practice? Both (minus the assignment), per the spec, are expressions that yeild values. The grammar needs two versions or the parse will be undecidable. The OP asks, what's the difference between the two. This post doesn't answer *that* question. – David-SkyMesh Dec 22 '13 at 07:25
  • @David-SkyMesh there're difference,consider below code `alert(funA()); //will alert hello` `function funA() {return "hello"}` `alert(funB()); //error` `funB = function(){return "hello"}` – Rick Li Dec 22 '13 at 11:28
  • @RickLi There is not. Expression-wise `(function x (){ 1; })` and `(function (){ 1 })` are identical in value. Depending on usage the first form has a side-effect; assignment to the `x` "slot" of the NULL (global) scope. I say 'depending on' because you could use that form within some data-structure (or as some other type of sub-expression) and it would not have said side-effect. – David-SkyMesh Dec 22 '13 at 23:59
0

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);
Entropyk
  • 117
  • 4
0

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
S.Serpooshan
  • 7,608
  • 4
  • 33
  • 61
  • Thanks for your answer! About the person, when I learned at code academy they used the function speak just like I did in my question and it worked. Any idea why then? – kfirba Dec 22 '13 at 08:33
  • @kfirba I would like to see that, speak would only work if you call it setting the invoking object explicitly. Code you provided would put speak on the global object (window) so when you execute `speak()` is the same as `window.speak();` and the invoking object (`this`) would be window unless you use call to change the invoking object: `speak.call(personInstance);` – HMR Dec 22 '13 at 08:45
0
  • 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() ...

lastboy
  • 566
  • 4
  • 12
  • 1
    I think it's called invoking object, the value of `this` is not related to scope. – HMR Dec 22 '13 at 08:52
  • The name is not the issue here.. call it whatever you want... the function 'this' is pointing to the scope that it was created in (if not using 'new') – lastboy Dec 22 '13 at 09:39