javascript程序员必须知道的知识: 变量的作用域(scope)
评判一个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
共同学习,写下你的评论
评论加载中...
作者其他优质文章