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