JavaScript:作用域:函数作用域/全局变量污染/命名空间
2021-03-09 14:30
标签:rip 调用 out 而且 query 代码 执行 显示 描述 在C#中我们都基本上不讲作用域,因为一切都是自然而然的(用语言描述反而有些困难)。但JavaScript的作用域,让人非常头大! 如果一个变量在函数体内部(用var)声明,则该变量的作用域为整个函数体,在函数体外不可引用该变量。(另见:let) 不同函数内部的同名变量互相独立,互不影响。 这样被声明的变量被称之为:局部变量。 不在任何函数内定义的变量具有全局作用域,被称之为全局变量。 演示: 如果script只是在HTML页面中使用,全局变量还可以接受(而且比较方便); 但随着JavaScript规模扩大,一个项目可能引用多个(第三方/其他人写的)类库(js文件),各个文件间的名称冲突就越来越难以避免,给开发/维护带来极大的问题!这就被称之为“全局变量污染”。 词法作用域 观察以下代码: reallySmart()调用smart(),smart()中需要sname但又没有声明sname,怎么办? 由var声明的变量的作用范围,其作用域由是由其源代码的书写位置,(而不是在哪里执行)决定的。 JavaScript的函数中不仅可以使用全局变量,还可以使用该函数外部的函数所声明的变量: 这样就形成了一个作用域链:JavaScript会沿着这个链条由内向外查找,直到undefined。 @想一想@:如何剪切/粘贴第一个函数,才能显示:子祥最帅? 其他成熟的工程化语言内置了名称空间(namespace)来解决这个问题,比如: JavaScript只能模拟: JQuery等类库就是这样做的。(演示) 把我们之前的代码稍作改动: @猜一猜@:会有什么结果? 如果在JavaScript的函数中声明变量,不使用var,该变量就具有全局作用域!——特性超级坑爹的一个“特性(bug)”,尤其是在代码review的时候,你根本不知道这是在: 所以从ES5开始,JavaScript就引入了所谓的“严格”模式,在代码顶部添加一行: 使用严格模式,就能强制JavaScript声明变量时必须使用:var;否则会报错。(以及其他约束) 演示:调试窗口报错 官方推荐总是使用严格模式。但是,如果 b.js 文件没有声明‘use strict‘且没有按照严格模式书写代码 @想一想@:会出现什么情况? 所以,更多时候,我们不得不把‘use strict‘声明在函数顶部。 体会:JavaScript在处理大型项目,进行工程化开发方面先天不足!由此诞生了很多“奇巧淫技”,以及不断进化的ES标准。 但你以为这样就结束了?too young too simple啊!作为一个“先天严重不足,后天各种补丁”的语言,这一切才刚刚开始…… 使用“模拟名称空间”技术,构建一个函数函数yz.fei.get(number); JavaScript:作用域:函数作用域/全局变量污染/命名空间 标签:rip 调用 out 而且 query 代码 执行 显示 描述 原文地址:https://www.cnblogs.com/nntisn351/p/14174958.html
局部变量
function scope() {
var sname = ‘李志博‘;
console.log(‘in function:‘ + sname);
}
scope();
console.log(‘out function:‘ + sname);
全局变量“污染”
var sname = "飞哥";
function smart() {
alert(`${sname}最帅`);
}
function reallySmart() {
var sname = ‘子祥‘;
smart();
}
reallySmart();
function outFunc(sname) {
var age = 100;
function innerFunc() {
alert(age); //age定义在innerFunc()之外
}
innerFunc();
}
名称空间(namespace)
//虽然都是“源栈”,但他们显然是不一样的:
China.Chongqing.Luckystack
China.Bejin.Luckystack
US.NewYork.Luckstack
var China = {};
China.Chongqing = {};
China.Chongqing.LuckyStack = {};
China.Chongqing.LuckyStack.wpz = function () {
strict模式(ES5)
function scope() {
/*var*/ sname = ‘李志博‘; //注释掉var
‘use strict‘; -- 如果浏览器不支持?
作业
让yz.fei.get(number)调用has9()/has8()/has6(),实现之前“统计含9/8/6数字个数”的作业
下一篇:Spring注解驱动——IOC
文章标题:JavaScript:作用域:函数作用域/全局变量污染/命名空间
文章链接:http://soscw.com/index.php/essay/62326.html