JavaScript 进阶(二)变量作用域

局部变量陷阱

先看一段代码:

function foo() {
    var a = "hello"
    b = "world"
    return a + b;
}

这个函数执行完成之后返回helloworld,结果确实没有问题。但是里面有一个细节就是两个局部变量一个前边有var,另一个没有。这似乎并不影响执行,但是事实上没有var的话,这个变量就变成了全局变量。你在这个函数外面调用一下alert(b)试一下就知道了。一个莫名其妙冒出来的全局变量在有时候会引起匪夷所思的bug,所以一定要记得局部变量声明前一定要用var

变量声明提升

再看一段代码:

var foo = "hello"
function test() {
    alert(foo);
    var foo = "world";
}
test()

代码执行时,请问alert的内容是什么呢?答案是undefined。从直觉上来讲,运行alert的时候,foo这个变量没有声明,不存在。既然局部作用域没有,那就去全局作用域找,应该是"hello"才是啊。为什么呢?这就是变量声明提升。函数内的任何变量的声明都会被提升至函数的顶部,所以上面的test函数相当于

function test() {
    var foo;
    alert(foo);
    foo = "world";
}

所以会是undefined。这里注意提升的只是声明,赋值的代码还在原来的地方。并且声明的部分与声明的代码是否执行无关,比如

function test() {
    alert(foo);
    if(false) {
        foo = "world";
    }
}

把test函数修改成这个样子,执行结果仍然是一样。声明仍然被提前了,尽管这行代码将不会被运行。
这就是变量声明提升,我们再看一个例子

function test() {
    foo1();
    foo2();
    function foo1(){alert("foo1")}
    var foo2 = function(){alert("foo2")}
}

当test函数执行的时候,结果如何呢?结果是foo1被alert出来,然后JS报错"undefined is not a function"。这里在函数内部声明函数的提升有点区别。foo1,用函数的方式声明定义一个函数,则声明与函数体都被提升了,但是foo2用变量的方式定义函数,被提升的只有声明,函数体没有被提升,所以执行foo2()的时候,foo2没有被赋值,是undefined。

看起来由于JS里面有变量声明提升,那么就无法使用C语言里面的块级作用域,那么我确实想用,怎么办呢?有一个办法是用匿名函数,举例如下:

var foo = "hello"
function test() {
    alert(foo);
    (function(){
        var foo = "world";
    })()
}
test()

当test函数改成这个样子的时候,alert出来的结果就是"hello"了,匿名函数里面的foo就无法作用到其他地方。

闭包中的局部变量

我之前招聘前端,问了应聘者这样一个题目,说请写一个可以返回递增整数序列的函数,他给我的答案是这样

var i = 0;
function increase() {return i++;}

当反复调用函数increase的时候,就会返回递增序列。但是我接着问,如果有人失手改了i怎么样,他语塞。其实这个问题的关键是说要制造一个很安全的地方来放置这个i,让这个变量只能被一个函数访问,所以一个可选的答案是这样。此时increase就是会返回递增序列。并且i放在了一个很安全的地方。就不会被破坏了。

var increase = (function() {
	var i = 0;
	return function(){return i++;}
})();

JS的闭包是一个很值得讲的内容,好用,但是也有不少坑,下面我专门开一篇文章来讲。

全局变量

无数讲高质量代码的书籍都会提到全局变量这个大杀器,程序员们都被反复告诫,除非你又充足的理由,否则不要使用全局变量,JS也不例外。然而JS有一个特殊的地方就是没有main方法,入口的代码一定要写,但是写在这地方的代码难免要用到变量,这些变量就是全局变量了,那么如何处理这个问题呢?答案还是匿名函数,像这样:

(function(){
    var a = "a";
    var b = "b";
    var c = "c";
    foo(a, b, c);
})()

把入口代码放到一个匿名函数中,这样这些变量a, b, c就会被藏到这个函数里面,就避免了全局变量的出现。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在jQuery中,变量作用域遵循JavaScript作用域规则。 在jQuery中,可以使用`var`关键字声明变量。声明的变量作用域可以是全局作用域或局部作用域。 1. 全局作用域:在任何函数外部声明的变量都具有全局作用域,可以在整个脚本中访问。这意味着在任何地方都可以使用这些变量,包括不同的函数和事件处理程序。 ```javascript var globalVariable = 'I am a global variable'; function foo() { console.log(globalVariable); } foo(); // 输出:I am a global variable ``` 2. 局部作用域:在函数内部声明的变量具有局部作用域,只能在声明它们的函数内部访问。这意味着这些变量只在其所在的函数范围内可见。 ```javascript function bar() { var localVariable = 'I am a local variable'; console.log(localVariable); } bar(); // 输出:I am a local variable console.log(localVariable); // 报错:localVariable is not defined ``` 需要注意的是,在JavaScript中,没有块级作用域。因此,在使用`if`语句、循环等代码块时,声明的变量仍然属于函数作用域。 ```javascript function baz() { if (true) { var blockVariable = 'I am a block variable'; } console.log(blockVariable); } baz(); // 输出:I am a block variable ``` 总结起来,jQuery中的变量作用域遵循JavaScript作用域规则。在函数内部声明的变量具有局部作用域,可以在整个函数内部访问。在函数外部声明的变量具有全局作用域,可以在整个脚本中访问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值