CoffeeScript作用域

2018-08-23 16:00 更新

先看几个例子:
age 变量在函数定义之前定义的例子
age = 99
r = -> age = 0
r()
console.log “i am #{age} years old”
#puts “i am 99 years old”


age 变量在函数定义之后定义的例子


r = -> age = 0
age = 99
r()
console.log “i am #{age} years old”
#also puts “i am 99 years old”


age 变量在函数外无定义的例子


r = -> age = 0
r()
console.log “i am #{age} years old”
#ReferenceError: age is not defined


很显然 CoffeeScript 中的变量作用域与 Javascript 中是一样的。其中有三条规则:
每个函数都是一个独立作用域,创建一个函数是创建作用域的唯一方法;(可参考 javascript 核心函数的说明)
变量的作用域仅在其被定义的范围内有效;
在变量的作用域以外,其是不可见的。
那为什么函数中直接用 age 做变量并赋值却没有改变全局变量 age (r函数之外的那个变量)的值呢?
因为 coffee 程序解析成 js 程序时,r 函数内通过 var 关键字重新定义了 age,使得 age 成为 r 函数内的一个变量,此变量的作用域仅为 r 函数内部,而不影响外部的 age 变量,以上第一个例子解析成 js 就是:


var r, age;
age = 99;
r = function() {
var age;
return age = 0;
};
r();
console.log(“i am ” + age + ” years old”);
如果将例子中 r 函数中的语句改为:
age = 99
r = -> age++
r()
console.log “i am #{age} years old”
#puts “i am 100 years old”


或者其他非赋值语句,此时的 age 则为全局中的 age 变量。



CoffeeScript编译器会考虑所有变量,保证每个变量都在词法域里适当地被定义,你永远不需要自己去写 var。那么在不同的上下文环境下出现了同名变量,CoffeeScript是怎么处理的呢,看个例子:


#编译前
outer = 1
fn = ->
 inner = -1
 outer = 10
 return null
inner = 4


//编译后
var fn, inner, outer;


outer = 1;


fn = function() {
 var inner;
 inner = -1;
 outer = 10;
 return null;
};


inner = 4;
在最外层的作用域下声明了outer、inner、fn,变量的定义都被推到相关的顶层作用域了。在fn函数内部只声明了inner,没有声明outer。实际上CoffeeScript变量定义是跟作用域和声明顺序有关的,看CoffeeScript代码fn的代码块,因为在fn里outer定义之前,函数外已经定义了outer,所以outer不在重新声明。 那为啥外面也声明了inner,fn内部又重新定义了inner,因为顺序的原因,函数fn内部的声明在前,所以编译后的代码重新定义了inner。函数外部是拿不到函数内的变量的,所以外部的inner在外围的作用域下也声明了inner。大家看下下面的代码,有助于理解:


外部先声明:


#编译前
outer = 1
inner = 4
fn = ->
 inner = -1
 outer = 10
 return null


//编译后
 var fn, inner, outer;


 outer = 1;


 inner = 4;


 fn = function() {
 inner = -1;
 outer = 10;
 return null;
};


函数内部先声明:


#编译前
 fn = ->
 inner = -1
 outer = 10
 return null
 outer = 1
 inner = 4


//编译后
 var fn, inner, outer;


 fn = function() {
 var inner, outer;
 inner = -1;
 outer = 10;
 return null;
};


 outer = 1;
 inner = 4;


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号