访问javascript严格函数

访问javascript严格函数,javascript,function,strict,Javascript,Function,Strict,我正在学习Javascript的“使用严格”模式,面临一个小问题。。如果我的理解是正确的,请纠正我 file1.js (function () { 'use strict'; var testObject = { "id" : 1, "label" : "Object 1" }; printUserInformation = function (userName){ console

我正在学习Javascript的“使用严格”模式,面临一个小问题。。如果我的理解是正确的,请纠正我

file1.js

(function () {
    'use strict';

     var testObject = {
            "id" : 1,
            "label" : "Object 1"
        };

     printUserInformation = function (userName){
          console.log(" Test Object is "+testObject + " User is "+ userName );
     }
});
file2.js

printUserInformation("StackOverflow User");

但当我从外部严格模式调用函数时,会出现未定义的错误,并且无法访问testObject。任何指南都是有用的。

主要问题与严格模式无关。您的
printUserInformation
函数的作用域仅限于您放入它的匿名函数,它不是全局函数,因此
file2.js
无权访问它。还有两个其他问题:您从未调用作用域函数,因此其中的代码(包括定义
printUserInformation
的代码)从未运行过,如果是,它将抛出
ReferenceError
,因为您试图分配给未声明的变量(
userInformation
),这会在严格模式下导致错误

如果您只想为
file1.js
启用严格模式而不避免创建全局变量,则不需要作用域函数:

'use strict';

var testObject = {
       "id" : 1,
       "label" : "Object 1"
};

var printUserInformation = function (userName){
      console.log(" Test Object is "+testObject + " User is "+ userName );
};
这解决了所有三个问题。前两个是通过删除作用域函数来处理的(这确实意味着代码创建了两个全局函数);第三个变量(未声明的变量)通过在以
printUserInformation=function…
开头的行前面添加
var
来修复。我还添加了一个
位于该函数表达式的末尾,因为您需要一个
位于赋值语句的末尾


在您询问的评论中:

您能告诉我如何使用
(function(){printUserInformation…})

如果您想使用作用域函数(这通常是一个好主意),但要在其中创建全局函数,您有两个选项:

  • 在调用作用域函数时,返回要将其公开的内容

  • 通过指定给全局对象上的属性,在作用域函数中创建全局对象

  • 下面是#1的样子:

    var printUserInformation = (function() {
        'use strict';
    
        var testObject = {
               "id" : 1,
               "label" : "Object 1"
        };
    
        var printUserInformation = function (userName){
              console.log(" Test Object is "+testObject + " User is "+ userName );
        };
    
        return printUserInformation;
    })();
    
    请注意,我们不仅定义了作用域函数,还调用了它(最后的
    ()
    ),这是问题代码中缺少的

    在那里,
    testObject
    仍然被很好地包含(它不是一个全局对象),但是
    printUserInformation
    是一个全局对象

    我应该注意到,围绕函数的paren在这里并不是绝对必要的,但是因为如果我们不在某个地方分配结果,它们是必要的,所以人们习惯于看到它们
    var x=function(){return 42;}()有效(
    x
    将是
    42
    ),但很可能会扔人

    以下是#2外观的众多方式之一:

    在全局范围而非严格模式下,
    引用全局对象。因此,我们将该引用作为参数,
    global
    传递到作用域函数中。严格模式在作用域函数内部有效,但不在其外部有效

    在浏览器上,您可以使用
    窗口
    ,而不是使用
    ,它是引用全局对象的全局对象(例如,全局变量)的属性。因此,您可以这样做:

    (function() {
        'use strict';
    
        var testObject = {
               "id" : 1,
               "label" : "Object 1"
        };
    
        window.printUserInformation = function (userName){
              console.log(" Test Object is "+testObject + " User is "+ userName );
        };
    })();
    
    但这只适用于浏览器,而不适用于其他环境(NodeJS、SilkJS等)

    使用范围函数非常方便。在像浏览器这样的环境中,全局名称空间非常拥挤,避免创建全局名称空间是一件好事(tm)。如果您不使用AMD(RequireJS等),通常最好只创建一个全局对象,这是一个可以放置任何其他内容的对象。其模式如下所示:

    // This bit is in each file: It creates the `MyApp` global and
    // initializes it with a blank object if it doesn't already exist,
    // or just uses the existing MyApp object if it already exists.
    var MyApp = window.MyApp || {};
    
    // Then we define this file's contents inside a scoping function
    (function() {
        "use strict";
    
        // ...private stuff here...
    
        // Let's make one public function
        MyApp.printUserInformation = function() { /* ... */ };
    })();
    

    (在非浏览器环境中,您可以在上面将
    window
    更改为
    this

    从这个JSFIDLE:I get
    ReferenceError:printUserInformation未定义
    。因此,您得到了一个未执行的严格函数,该函数包含一个局部变量和一个隐式全局变量。
    使用严格必须出现在文件的顶部不是it@surajck:不,那不正确。@surajck:比那稍微复杂一点,但基本上,是的。试过这个:它能工作。所以问题在于范围,而不是经常使用strict
    Thnx,你能告诉我如何使用(function(){printUserInformation…})@T.J.克劳德,你是对的,我只是习惯于重复一些东西让自己明白。“没有什么是想抢别人的风头的。@数字炼金术士:我第一次听到你说的。:-)我已经更新了答案来解决这个问题。
    // This bit is in each file: It creates the `MyApp` global and
    // initializes it with a blank object if it doesn't already exist,
    // or just uses the existing MyApp object if it already exists.
    var MyApp = window.MyApp || {};
    
    // Then we define this file's contents inside a scoping function
    (function() {
        "use strict";
    
        // ...private stuff here...
    
        // Let's make one public function
        MyApp.printUserInformation = function() { /* ... */ };
    })();