为了账号安全,请及时绑定邮箱和手机立即绑定

javascript程序员必须知道的知识: 变量的作用域(scope)

标签:
JavaScript

评判一个js程序员的能力的标准之一,就是看他对于作用域掌握的功力如何.
下面是js中常见的一些例子. 总结出来希望对大家有用:

1.全局变量

var color = 'red';
function show(){
   console.info(color);
}

show()   // => red

在浏览器模式下(chrome, firefox...)下面三个声明是等价的:

color = 'red'  // 不带var 就是全局变量. 
this.color = 'red'
window.color = 'red'

但是比较好的实践是, 定义一个全局变量, 然后 我们直接引用它:

global_vars = {}  // 定义一个全局变量
然后 
global_vars.color = 'red'
global_vars.model = 'apple'

2.普通变量, 局部作用域 (local scope) , 也就是最常见的作用域.

function show(){
  var color = 'green'
  console.info(color)
}

show()  // => 'green'

3.if作用域产生的变量:

例子1:

function show(){
  if(true){
    var color = 'green'  // color 变量是在if 分支中创建的
  }

  console.info(color) // 居然也能正常使用. 
}

show()
# => green

例子2:

color = 'yellow' // 注意这里多了一个外围作用域的 color
function show(){
  if(true){
    var color = 'green'  // 在if 分支中声明 color
  }

  console.info(color) // => 结果打印出来,还是if 声明出来的变量的优先.
}

show()
# => green  

4.function 与 this, new: (内容开始烧脑了)

例子1: 最简单的例子, this 指的是 show()这个function(function, this.color 则为它增加了个属性 color.

function show(){
  this.color = 'green'
}
console.info(new show().color) // => 'green'

例子2: 如果function内使用了this, 名称与外部作用域的某个变量名称一样, 它们实际互不影响.

color = 'yellow'  // 全局变量 color

function show(){
  this.color = 'green'  // show()的 color属性
}

console.info(new show().color)  // => green
console.info(color)   // yellow

5.Closure中, 可以直接使用外围的变量.

function show(){
  var color = 'red';
  return function(){
    console.info(color)  // 可以直接使用与该closure同级的变量.
  }
}

show()    // 返回 function(){ console.info(color) }
show()()  // => red

6.对于function 在函数声明中的属性, 可以通过"new "之后, "." 来访问. (不能通过prototype来访问)

直接看例子:
例子1:

function show(){
  this.green = 'green' // 声明了一个 属性: this.green
}

//那么该属性只能通过 new 才能访问.
new show().green   // => green

// 不能通过prototype.green 来访问. 它们是两个东西.
show.prototype.green  // => undefined 

例子2: 但是,对于prototype定义的属性, 却可以通过 "new xx.y" 的方式来访问.

function show(){
  this.green = 'green'
}

show.prototype.red = 'red'  // 通过prototype 来设置 red 
console.info(show.prototype.red)  // 可以直接通过prototype.red访问
console.info(new show().red) // 也可以通过 "new xx.y" 的形式来访问.

例子3: 在函数声明中初始化的属性,跟 prototype设置的属性,哪怕名字相同, 得到的结果也不一样.

function show(){
  this.green = 'green'  // 属性名叫 green, 被初始化成 'green'
}

console.info(show.prototype.green)  // => undefined
console.info(new show().green)      // => green

show.prototype.green = 'dark-green' // 通过prototype的方式来设置 属性. 
console.info(show.prototype.green)  // => dark-green
console.info(new show().green)      // => green   你是不是惊呆了. 切记这一点! node, browser中都是同样结果.

7.全局变量与 closure中的变量.

例子1: closure中可以直接使用 外围定义的变量:

var color = 'red';

(function () {
  console.log(color);   // color变量已经被外层定义了.
})();                      

// => red  

例子2: 如果要在closure中覆盖外围变量的话,就要当心了:

var color = 'red';

(function () {
  console.log(color);     // => undefined
  var color = 'green';    
  console.log(color);     // => green
})();

为什么会这样呢? 因为, js在衡量某个代码时,会先私下把某个变量的"声明"在当前的作用域中置顶, 然后在对它"赋值":

上面的代码,"可以认为"它等同于:

var color = 'red';

(function () {
  var color;              // 在这里对 color 做了"声明"
  console.log(color);     // => undefined
  color = 'green';        // 在这里对 color "赋值". 
  console.log(color);     // => green
})();

8.try-catch中的变量与作用域

直接看例子:

var color = 'red';
console.info(color)      // => red

try {
  throw 'green'
}catch(color) {
  console.info(color)    // => green
}

console.info(color)      // => red
点击查看更多内容
39人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消