Bran Tran
Bran Tran

Reputation: 187

Closures with functions as object members

My question sounds simple: does a function defined as an object member have closure over function's scope which contains the object?

For example:

    function foo() {
      /* some
       *  code*/

     var obj = {
            prop1: //something;
            prop2: //something;
            someCoolProp: function() {
                  //code
             }
     }
}

Does the someCoolProp function reference have closure over the scope of foo? Where is the anonymous function defined so if we gave it a name where would it be accessible?

Thanks.

Upvotes: 3

Views: 38

Answers (3)

GameTag
GameTag

Reputation: 379

When you declare a function a new scope is created, that's means all property inside it are private so none other scope can call these property. Let me explain with different examples because it's really important to understand this.


Here, you can't call x in the window scope, x is only inside the foo() scope

function foo() {
  var x = 'Hey';
  
  function transformX( val ){
    // I can call x because transformX is inside Foo()
    x = 'Ho';
  }
  
  return transformX(x);
}

console.log( foo() ); // 'Ho'
console.log( x ); // Reference Error can't read x


Here it's a ****** bad practice, I declare y without the var keyword, so at first window doesn't know y but during bar() execution y is declared & attached inside the window scope (default behavior) ! Always use a keyword declaration : var | let | 'const`

function bar() {
  y = 'Hey';
  
  function transformX( val ){
    y = 'Ho';
  }
  return transformX(y);
}

console.log( y ); // 'Error y is not defined'
bar();
console.log( y ); // 'Ho'


This example is pretty hard than before, you can see a people variable inside the peopleObject and inside the window object. This practice is good to keep some variables like private.

var peopleObject = function(){
  
  var people = {
    name: 'Yann',
    age: 25
  }
  
  function sayMyName(){
    console.log('Hi', people.name);
  }
  
  function getName(){
    return people.name;
  }
  
  return {
    name : getName,
    p: people
  };
  
};

var people = peopleObject();
console.log( people.name() );
console.log( people.p );
console.log( people.sayMyName() ); // error sayMyName is not a function

Hi hope it's gonna help you :)

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

My question sounds simple: does a function defined as an object member have closure over function's scope which contains the object?

Yes, it has.

function foo() {
    var bar = 42,
        obj = {
            prop1: 'something',
            prop2: 'something',
            someCoolProp: function() {
                console.log(bar);
            }
        };

    return obj;
}

foo().someCoolProp();

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074595

My question sounds simple: does a function defined as an object member have closure over function's scope which contains the object?

Does the someCoolProp function reference have closure over the scope of foo?

Yes. It being defined within the object initializer doesn't have any effect at all on what it closes over. It still closes over the context of the call to foo that created it.

Where is the anonymous function defined so if we gave it a name where would it be accessible?

As of ES2015, that function does have a name: someCoolProp. (ES2015 added a lot of function name inference to the specification; a large number of "anonymous function expressions" no longer create anonymous functions, amusingly.) That name isn't added to any execution context's binding object (loosely, "scope"), though; the only reference to the function that exists is on the object's property of the same name.

But if you mean, if you used a named function expression:

var obj = {
    prop1: //something;
    prop2: //something;
    someCoolProp: function someNameHere() {
    //                     ^^^^^^^^^^^^---------------- added
        //code
    }
}

...the situation is the same: Because it's a function expression, the name isn't added to the context where it's defined. (Whereas with a function declaration, it is.)

Upvotes: 1

Related Questions