“a”是什么;作用域函数“;用javascript?

“a”是什么;作用域函数“;用javascript?,javascript,Javascript,作者说,在这方面 对象文本不需要使用新运算符进行实例化,但 不应在语句开头使用,因为开头{可能是 解释为块的开始。在对象外部,新建 成员可以通过以下方式使用赋值添加到其中 myModule.property=“someValue” 下面我们可以看到使用 对象文字表示法: 使用对象文字有助于封装和组织 code和Rebecca Murphey之前在 如果您希望进一步读入对象文字,请选择“深度” 也就是说,如果我们选择这种技术,我们可能会 对模块模式感兴趣。它仍然使用对象文本,但 仅作为作用域函数的

作者说,在这方面

对象文本不需要使用新运算符进行实例化,但 不应在语句开头使用,因为开头{可能是 解释为块的开始。在对象外部,新建 成员可以通过以下方式使用赋值添加到其中 myModule.property=“someValue”

下面我们可以看到使用 对象文字表示法:

使用对象文字有助于封装和组织 code和Rebecca Murphey之前在 如果您希望进一步读入对象文字,请选择“深度”

也就是说,如果我们选择这种技术,我们可能会 对模块模式感兴趣。它仍然使用对象文本,但 仅作为作用域函数的返回值。

我的问题: 他所说的“它仍然使用对象文本,但仅作为作用域函数的返回值”是什么意思

具体地说,什么是“作用域函数”

在JavaScript中,用
var
声明的变量是“函数范围”的,而不是像在其他类似C语言中那样的“块范围”(以及{}语法可能意味着什么)。(更新Re:block scoping:ES6引入了带有两个新变量声明的块作用域,
let
const
。请参阅)

使用“作用域函数”创建模块意味着使用函数包装变量范围和可能使用的其他逻辑,然后返回包含所需结果的对象文字

例如:

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

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

    return person;
}
Josh提到的IIFE和closure的例子也是“作用域函数”的一个有价值的用法

另一个例子:

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

每次调用
generateId()
,它都会返回下一个整数。

非常确定它引用的是一个立即调用的函数表达式,因此模块中存在的所有数据都是“作用域”(私有的,不影响全局作用域,无论您如何调用它):

这几乎等同于用对象文字表示法写出一个模块,除了使用这种模式之外,您还可以获得作用域不相互冲突的好处(即,IIFE之外的任何作用域都与IIFE内的作用域分开)

注:

模块模式使用闭包封装“隐私”、状态和组织


在javascript中,我们有一个称为函数作用域的东西,这意味着函数中声明的变量只在该函数中可见,更多关于作用域的内容,在ES6之前,这是使用全局作用域中的隔离函数和变量创建模块的唯一方法,因此它们不能覆盖现有函数和变量具有相同名称的变量用于将要隔离的功能包装在IIFE(立即调用的函数表达式)中。这些函数在定义后立即运行,并创建“外部世界”看不到的隔离变量和函数范围,或者说是全局范围,即

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();

在上面的示例中,我们首先在全局范围中定义一个
sayHello
函数,然后在该函数中定义一个IIFE,返回一个包含函数
sayHello
的对象文本,并将其分配给一个名为personModule的变量。函数
personModule.sayHello
创建一个闭包,因为它包含一个引用ce到IIFE作用域的
name
变量。IIFE已执行,但IIFE函数的函数作用域仍保留在内存中,垃圾收集器不会收集它,因为
personModule.sayHello
函数将在定义函数的词法作用域和对
name
variable保持此函数作用域处于活动状态。换句话说,sayHello保持对定义函数的周围状态的引用,此行为称为闭包上下文。最后,我们必须使用值为“Viktor”的
name
变量这是在全局函数的作用域中定义的,一个值为“Adam”它位于IIEF函数作用域中,对外部作用域(包括全局作用域)不可见。访问此变量的唯一方法是通过
personModule.sayHello
。这样一来,一个
name
变量不会覆盖另一个
name
变量,并且两个变量在不同的s中都具有不同的值处理。

链接在我的帖子中不起作用,这里是:“函数作用域,而不是块作用域”适用于ES6中的
var
,但不适用于
let
。这个答案需要在描述事物时注意ES6。
var somethingInTheGlobalScope = true;

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

  return {
    myModuleMethod1: function() {},
    myModuleMethod2: function() {}
  }
})();
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();