最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

What is a "scoping function" in javascript? - Stack Overflow

programmeradmin5浏览0评论

In Learning Javascript Design Patterns, the author says

Object literals don't require instantiation using the new operator but shouldn't be used at the start of a statement as the opening { may be interpreted as the beginning of a block. Outside of an object, new members may be added to it using assignment as follows myModule.property = "someValue";

Below we can see a more plete example of a module defined using object literal notation:

var myModule = {

  myProperty: "someValue",

  // object literals can contain properties and methods.
  // e.g we can define a further object for module configuration:
  myConfig: {
    useCaching: true,
    language: "en"
  },

  // a very basic method
  saySomething: function () {
    console.log( "Where in the world is Paul Irish today?" );
  },

  // output a value based on the current configuration
  reportMyConfig: function () {
    console.log( "Caching is: " + ( this.myConfig.useCaching ? "enabled" : "disabled") );
  },

  // override the current configuration
  updateMyConfig: function( newConfig ) {

    if ( typeof newConfig === "object" ) {
      this.myConfig = newConfig;
      console.log( this.myConfig.language );
    }
  }
};

// Outputs: Where in the world is Paul Irish today?
myModule.saySomething();

// Outputs: Caching is: enabled
myModule.reportMyConfig();

// Outputs: fr
myModule.updateMyConfig({
  language: "fr",
  useCaching: false
});

// Outputs: Caching is: disabled
myModule.reportMyConfig();

Using object literals can assist in encapsulating and organizing your code and Rebecca Murphey has previously written about this topic in depth should you wish to read into object literals further.

That said, if we're opting for this technique, we may be equally as interested in the Module pattern. It still uses object literals but only as the return value from a scoping function.

My Question: What does he mean by "It still uses object literals but only as the return value from a scoping function."

Specifically what is a "scoping function"?

In Learning Javascript Design Patterns, the author says

Object literals don't require instantiation using the new operator but shouldn't be used at the start of a statement as the opening { may be interpreted as the beginning of a block. Outside of an object, new members may be added to it using assignment as follows myModule.property = "someValue";

Below we can see a more plete example of a module defined using object literal notation:

var myModule = {

  myProperty: "someValue",

  // object literals can contain properties and methods.
  // e.g we can define a further object for module configuration:
  myConfig: {
    useCaching: true,
    language: "en"
  },

  // a very basic method
  saySomething: function () {
    console.log( "Where in the world is Paul Irish today?" );
  },

  // output a value based on the current configuration
  reportMyConfig: function () {
    console.log( "Caching is: " + ( this.myConfig.useCaching ? "enabled" : "disabled") );
  },

  // override the current configuration
  updateMyConfig: function( newConfig ) {

    if ( typeof newConfig === "object" ) {
      this.myConfig = newConfig;
      console.log( this.myConfig.language );
    }
  }
};

// Outputs: Where in the world is Paul Irish today?
myModule.saySomething();

// Outputs: Caching is: enabled
myModule.reportMyConfig();

// Outputs: fr
myModule.updateMyConfig({
  language: "fr",
  useCaching: false
});

// Outputs: Caching is: disabled
myModule.reportMyConfig();

Using object literals can assist in encapsulating and organizing your code and Rebecca Murphey has previously written about this topic in depth should you wish to read into object literals further.

That said, if we're opting for this technique, we may be equally as interested in the Module pattern. It still uses object literals but only as the return value from a scoping function.

My Question: What does he mean by "It still uses object literals but only as the return value from a scoping function."

Specifically what is a "scoping function"?

Share Improve this question edited Dec 15, 2015 at 21:40 FishBasketGordo 23.1k4 gold badges59 silver badges92 bronze badges asked Dec 15, 2015 at 21:33 A.A. 1,6454 gold badges20 silver badges32 bronze badges 1
  • link didn't work in my post, here it is: addyosmani./resources/essentialjsdesignpatterns/book/… – A. Commented Dec 15, 2015 at 21:34
Add a ment  | 

3 Answers 3

Reset to default 2

In JavaScript, variables declared with var are "function scoped" not "block scoped" like in other C-like languages (and how the {} syntax might imply). (Update Re: block scoping: ES6 introduced block scoping with two new variable declarations, let and const. See https://www.freecodecamp/news/var-let-and-const-whats-the-difference/)

To create a module with a "scoping function" means to use a function to wrap the scope of variables and other logic you may use, and then return an object literal with the results you want.

Example:

function personFacory(name) {
    var person = {
        name: name
    };

    if (name === 'Bob') {
        person.isBob = true;
    }

    return person;
}

The case of the IIFE and closure @Josh mentions is also a valuable use of a "scoping function."

Another example:

var generateId = (function(){
   var currentId = 0; 
   return function() {
       return currentId++;
   };
})();

Each time you call generateId(), it will return the next integer.

Pretty sure it's referring to an immediately invoked function expression, so that all the data present in the module is "scoped" (private, not affecting the global scope, whatever you wanna call it):

var somethingInTheGlobalScope = true;

var myModule = (function() {
  var somethingThatOnlyExistsHere = true;

  return {
    myModuleMethod1: function() {},
    myModuleMethod2: function() {}
  }
})();

This IIFE is almost equivalent to just writing out a module in object literal notation, except with this pattern, you get the benefit of scopes not colliding with each other (i.e., any scope outside of your IIFE stays separate from the scope within the IIFE).

Note from Addy Osmani:

The Module pattern encapsulates "privacy", state and organization using closures.

Well in javascript we have a thing called function scope which means that the variable declared within a function are visible only within that function, more on scopes and hoisting here https://www.digitalocean./munity/tutorials/understanding-variables-scope-hoisting-in-javascript Before ES6 the only way to create modules with isolated functions and variables from the global scope so they cannot override already existing functions and variables with the same names was to wrap the functionality you want to isolate in an IIFE (Immediately Invoked Function Expression) https://developer.mozilla/en-US/docs/Glossary/IIFE. These are functions that run as soon as they are defined and create an isolated scope of variable and function that isn't visible to the "outside world" or said otherwise the global scope i.e.

function sayHello() {
    var name = "Viktor"

    var personModule = (function() { //Here we define our IIFE
       var name = "Adam";

       return { //Here we return an object literal with a scoping function
           sayHello: function() {
               console.log("Hello my name is " + name);
           }
       }
    }())

    personModule.sayHello() //This will print "Hello my name is Adam"
    console.log("Hello my name is " + name) //This will print "Hello my name is Viktor"
}

sayHello();

In the sample above first we define a sayHello function in the global scope and after that in it we define an IIFE that returns an object literal with the function sayHello in it and assign it to a variable called personModule. The function personModule.sayHello creates a closure because it holds a reference to the name variable of the IIFE scope. The IIFE is already executed but the function scope of the IIFE function remains in memory and it isn't collected by the garbage collector because the personModule.sayHello function will be executed outside the lexical scope where the function is defined and the reference to the name variable keeps this function scope alive. Said in other words personModule.sayHello keeps a reference to the surrounding state where the function is defined and this behavior is called a closure context https://developer.mozilla/en-US/docs/Web/JavaScript/Closures. At the end, we have to name variables one with the value "Viktor" that is defined in the global sayHello function's scope and one with the value "Adam" that lives in IIEF function scope and it is not visible to the outer scopes including the global scope. The only way to access this variable is through personModule.sayHello. This way the one name variable does not override the other name variable and both variables exist with different values in different scopes.

发布评论

评论列表(0)

  1. 暂无评论