CoffeeScript作用域

2018-08-23 16:00 更新

先看幾個(gè)例子:
age 變量在函數(shù)定義之前定義的例子
age = 99
r = -> age = 0
r()
console.log “i am #{age} years old”
#puts “i am 99 years old”


age 變量在函數(shù)定義之后定義的例子


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


age 變量在函數(shù)外無定義的例子


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


很顯然 CoffeeScript 中的變量作用域與 Javascript 中是一樣的。其中有三條規(guī)則:
每個(gè)函數(shù)都是一個(gè)獨(dú)立作用域,創(chuàng)建一個(gè)函數(shù)是創(chuàng)建作用域的唯一方法;(可參考 javascript 核心函數(shù)的說明)
變量的作用域僅在其被定義的范圍內(nèi)有效;
在變量的作用域以外,其是不可見的。
那為什么函數(shù)中直接用 age 做變量并賦值卻沒有改變?nèi)肿兞?age (r函數(shù)之外的那個(gè)變量)的值呢?
因?yàn)?coffee 程序解析成 js 程序時(shí),r 函數(shù)內(nèi)通過 var 關(guān)鍵字重新定義了 age,使得 age 成為 r 函數(shù)內(nèi)的一個(gè)變量,此變量的作用域僅為 r 函數(shù)內(nèi)部,而不影響外部的 age 變量,以上第一個(gè)例子解析成 js 就是:


var r, age;
age = 99;
r = function() {
var age;
return age = 0;
};
r();
console.log(“i am ” + age + ” years old”);
如果將例子中 r 函數(shù)中的語句改為:
age = 99
r = -> age++
r()
console.log “i am #{age} years old”
#puts “i am 100 years old”


或者其他非賦值語句,此時(shí)的 age 則為全局中的 age 變量。



CoffeeScript編譯器會(huì)考慮所有變量,保證每個(gè)變量都在詞法域里適當(dāng)?shù)乇欢x,你永遠(yuǎn)不需要自己去寫 var。那么在不同的上下文環(huán)境下出現(xiàn)了同名變量,CoffeeScript是怎么處理的呢,看個(gè)例子:


#編譯前
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,變量的定義都被推到相關(guān)的頂層作用域了。在fn函數(shù)內(nèi)部只聲明了inner,沒有聲明outer。實(shí)際上CoffeeScript變量定義是跟作用域和聲明順序有關(guān)的,看CoffeeScript代碼fn的代碼塊,因?yàn)樵趂n里outer定義之前,函數(shù)外已經(jīng)定義了outer,所以outer不在重新聲明。 那為啥外面也聲明了inner,fn內(nèi)部又重新定義了inner,因?yàn)轫樞虻脑?,函?shù)fn內(nèi)部的聲明在前,所以編譯后的代碼重新定義了inner。函數(shù)外部是拿不到函數(shù)內(nèi)的變量的,所以外部的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;
};


函數(shù)內(nèi)部先聲明:


#編譯前
 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;


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號