成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Lexical environments: Common Theory

羅志環(huán) / 3432人閱讀

摘要:調(diào)用棧意味著中的執(zhí)行環(huán)境棧,激活記錄意味著的激活對(duì)象。此外,所有的函數(shù)是一等公民。換句話說(shuō),自由變量并不存在自身的環(huán)境中,而是周?chē)沫h(huán)境中。值得注意的是,函數(shù)并沒(méi)有用到自由變量。在后面的情形中,我們將綁定對(duì)象稱(chēng)為環(huán)境幀。

原文

ECMA-262-5 in detail. Chapter 3.1. Lexical environments: Common Theory.

簡(jiǎn)介

在這一章,我們將討論詞法環(huán)境的細(xì)節(jié)——一種被很多語(yǔ)言應(yīng)用管理靜態(tài)作用域的機(jī)制。為了能夠更好地理解這個(gè)概念,我們也會(huì)討論一些別的——?jiǎng)討B(tài)作用域(ECMAScript中并沒(méi)有直接使用)。我們將看到環(huán)境是如何管理嵌套的代碼結(jié)構(gòu)和閉包。ECMA-262-5規(guī)范介紹了詞法環(huán)境,盡管這是一個(gè)和ECMAScript相獨(dú)立的概念,被應(yīng)用于很多函數(shù)。實(shí)際上,部分和這個(gè)話題相關(guān)的技術(shù)部分,我們已經(jīng)在之前的ES3系列中討論過(guò)了,例如變量和激活對(duì)象,作用域鏈。嚴(yán)格地來(lái)說(shuō),詞法環(huán)境相比ES3中的概念只是更加理論化,更加抽象。但這是一個(gè)ES5的年代,我建議用這些新的定義來(lái)討論和解釋ECMAScript。盡管,更加普遍的概念,例如激活記錄(activation record)(ES3中的激活對(duì)象)的調(diào)用棧(call-stack)(ES中執(zhí)行環(huán)境棧),等等,已經(jīng)在低級(jí)抽象的層面上討論過(guò)了。這一章節(jié)致力于環(huán)境的一般理論,也會(huì)涉及程序語(yǔ)言理論(programming languages theory)的部分。我們將從不同的角度,用不同的語(yǔ)言實(shí)現(xiàn),來(lái)理解為什么詞法作用域是需要的,以及這些結(jié)構(gòu)是如何被創(chuàng)建的。事實(shí)上,如果我們完全理解來(lái)作用域的一般理論,那些ES中的作用域問(wèn)題也就消失了。

一般理論

ES中的概念(激活對(duì)象,作用域鏈,詞法環(huán)境)都與作用域的概念相關(guān)。ES中提到的定義是作用域的一種本地實(shí)現(xiàn),及相關(guān)術(shù)語(yǔ)。

作用域

作用域是用來(lái)在程序的不同部分中管理變量的可見(jiàn)行和可訪問(wèn)性。一些
封裝的抽象概念(例如命名空間,模塊)都和作用域相關(guān),作用域被用來(lái)使系統(tǒng)更加模塊化以及避免命名變量的沖突。函數(shù)有本地變量,代碼塊有本地變量,作用域封裝了內(nèi)在的數(shù)據(jù),提升了抽象程度。作用域使我們?cè)谝粋€(gè)程序中使用相同的變量,但是代表不同的含義,擁有不同的值。從這個(gè)角度來(lái)說(shuō),作用域是個(gè)閉合的上下文,里面的變量都與值相關(guān)聯(lián)。我們也可以說(shuō),作用域是某個(gè)變量它某個(gè)含義的邏輯邊界。例如,全局變量,局部變量等,都反映了這個(gè)變量的聲明周期。代碼塊和函數(shù)讓我們擁有了一個(gè)主要的作用域的屬性——嵌套其他作用域或者被嵌套。因此,我們可以看到并不是所有的實(shí)現(xiàn)都支持函數(shù)嵌套,同樣不是所有的實(shí)現(xiàn)都提供塊級(jí)作用域。讓我們來(lái)考慮以下的C代碼:

// global "x"
int x = 10;
 
void foo() {
   
  // local "x" of "foo" function
  int x = 20;
 
  if (true) {
    // local "x" of if-block
    int x = 30;
    printf("%d", x); // 30
  }
 
  printf("%d", x); // 20
 
}
 
foo();
 
printf("%d", x); // 10

它可以被下圖表示

ECMAScript在版本6之前并不支持塊級(jí)作用域

var x = 10;
 
if (true) {
  var x = 20;
  console.log(x); // 20
}
 
console.log(x); // 20

ES6標(biāo)準(zhǔn)中let關(guān)鍵字可以創(chuàng)建塊級(jí)變量

let x = 10;
if (true) {
  let x = 20;
  console.log(x); // 20
}
 
console.log(x); // 10

這個(gè)塊級(jí)作用域可以通過(guò)匿名自調(diào)用函數(shù)來(lái)實(shí)現(xiàn)

var x = 10;
 
if (true) {
  (function (x) {
    console.log(x); // 20
  })(20);
}
 
console.log(x); // 10
靜態(tài)(詞法)作用域

在靜態(tài)作用域中,標(biāo)識(shí)符指向最近的詞法環(huán)境。單詞“l(fā)exical”在這個(gè)場(chǎng)合下指的是程序書(shū)寫(xiě)的屬性,詞法上變量出現(xiàn)的源文字,變量被聲明的地方。在那個(gè)作用域中,變量將會(huì)在運(yùn)行時(shí)被解析。單詞“static”意味著決定標(biāo)識(shí)符作用域是在程序的詞法分析(parsing)的過(guò)程中。這也就是說(shuō),在程序啟動(dòng)之前,我們通過(guò)閱讀代碼,就能判斷在哪個(gè)作用域下,變量將被解析。舉個(gè)例子

var x = 10;
var y = 20;
 
function foo() {
  console.log(x, y);
}
 
foo(); // 10, 20
 
function bar() {
  var y = 30;
  console.log(x, y); // 10, 30
  foo(); // 10, 20
}
 
bar();

在這個(gè)例子中,變量x在全局變量中被定義——意味著,運(yùn)行時(shí),它也將在全局對(duì)象中被解析。變量y有兩個(gè)定義,我們說(shuō)過(guò),考慮擁有變量最近的詞法作用域。變量自身所在的作用域擁有最高的優(yōu)先級(jí)。因此,在bar函數(shù)中,變量y被解析為30。bar函數(shù)中局部變量y覆蓋來(lái)同名的全局變量y。但是,同名變量y在foo函數(shù)中依然被解析為20,即使它在bar函數(shù)的內(nèi)部被調(diào)用,而且在bar函數(shù)內(nèi)部還有變量y。變量的解析和環(huán)境的調(diào)用是相互獨(dú)立的(in this case bar is a caller of foo, and foo is a callee)。因?yàn)閒oo函數(shù)被定義的位置,最近的含有變量y的詞法環(huán)境就是全局環(huán)境。如今,靜態(tài)作用域已經(jīng)被很多語(yǔ)言應(yīng)用:C, Java, ECMAScript, Python, Ruby, Lua等等。

動(dòng)態(tài)作用域

動(dòng)態(tài)作用域并不在詞法環(huán)境中解析變量,而是動(dòng)態(tài)形成變量棧。每當(dāng)碰到變量聲明,就把變量放進(jìn)棧中。變量的聲明周期結(jié)束時(shí),將變量從棧中彈出。來(lái)看一段偽代碼。

// *pseudo* code - with dynamic scope
 
y = 20;
 
procedure foo()
  print(y)
end
 
 
// on the stack of the "y" name
// currently only one value 20
// {y: [20]}
 
foo() // 20, OK
 
procedure bar()
 
  // and now on the stack there
  // are two "y" values: {y: [20, 30]};
  // the first found (from the top) is taken
 
  y = 30
 
  // therefore:
  foo() // 30!, not 20
 
end
 
bar()

環(huán)境的調(diào)用影響了變量的解析。[譯者注:不是重點(diǎn)不譯了]

名稱(chēng)綁定

在高級(jí)語(yǔ)言中,我們不在操作地址,這個(gè)地址指向內(nèi)存中的數(shù)據(jù),我們直接使用變量名來(lái)指代那些數(shù)據(jù)。名稱(chēng)綁定是標(biāo)識(shí)符和對(duì)象的關(guān)聯(lián)。一個(gè)標(biāo)識(shí)符可以綁定或解綁。如果標(biāo)識(shí)符被綁定了個(gè)對(duì)象,那么它就指向這個(gè)對(duì)象。

重新綁定

// bind "foo" to {x: 10} object
var foo = {x: 10};

console.log(foo.x); // 10

// bind "bar" to the same object
// as "foo" identifier is bound

var bar = foo;

console.log(foo === bar); // true
console.log(bar.x); // OK, also 10

// and now rebind "foo"
// to the new object

foo = {x: 20};

console.log(foo.x); // 20

// and "bar" still points
// to the old object

console.log(bar.x); // 10
console.log(foo === bar); // false

可變性
// bind an array to the "foo" identifier
var foo = [1, 2, 3];
 
// and here is a *mutation* of
// the array object contents
foo.push(4);
 
console.log(foo); // 1,2,3,4
 
// also mutations
foo[4] = 5;
foo[0] = 0;
 
console.log(foo); // 0,2,3,4,5

環(huán)境

在這一部分,我們將提到詞法作用域?qū)崿F(xiàn)的技術(shù)。我們將操作更抽象的實(shí)體,討論詞法作用域,在以后的解釋中,我們將用環(huán)境而不是作用域,因?yàn)镋S5中也是這個(gè)術(shù)語(yǔ),全局環(huán)境,函數(shù)的本地環(huán)境等等。正如我們提到的,環(huán)境說(shuō)明了表達(dá)式中標(biāo)識(shí)符的含義。ECMAScript用調(diào)用棧(call-stack)來(lái)管理函數(shù)的執(zhí)行。來(lái)考慮一些通用的模型來(lái)保存變量。一些事情很有趣,有閉包的系統(tǒng)和沒(méi)有閉包的系統(tǒng)。

激活記錄模型

如果沒(méi)有一等函數(shù),或者不允許內(nèi)部函數(shù),最簡(jiǎn)單存儲(chǔ)本地變量的方式就是調(diào)用棧本身。一個(gè)特殊的調(diào)用棧的數(shù)據(jù)結(jié)構(gòu)叫做激活記錄(activation record),被用來(lái)保存環(huán)境綁定。有時(shí)候也叫調(diào)用棧幀(call-stack frame)。每當(dāng)函數(shù)被調(diào)用,一個(gè)激活記錄(包含參數(shù)和本地變量)被壓入棧中。因此,當(dāng)函數(shù)調(diào)用其他函數(shù),另一個(gè)棧幀被壓入棧中。當(dāng)上下文結(jié)束來(lái),激活記錄從棧中彈出,意味這所有本地變量被銷(xiāo)毀。這個(gè)模型在c語(yǔ)言中被使用。
例如

void foo(int x) {
  int y = 20;
  bar(30);
}
 
void bar(x) {
  int z = 40;
}
 
foo(10);

調(diào)用棧會(huì)有如下變化

callStack = [];
 
// "foo" function activation
// record is pushed onto the stack
 
callStack.push({
  x: 10,
  y: 20
});
 
// "bar" function activation
// record is pushed onto the stack
 
callStack.push({
  x: 30,
  z: 40
});
 
// callStack at the moment of
// the "bar" activation
 
console.log(callStack); // [{x: 10, y: 20}, {x: 30, z: 40}]
 
// "bar" function ends
callStack.pop();
 
// "foo" function ends
callStack.pop();

當(dāng)bar函數(shù)被調(diào)用時(shí)

很多相似的函數(shù)執(zhí)行的邏輯方法在ECMAScript被使用。然后,有些很重要的不同。調(diào)用棧意味著ES中的執(zhí)行環(huán)境棧,激活記錄意味著ES3的激活對(duì)象。和C不同的是,ECMAScript不會(huì)從內(nèi)存中移除激活對(duì)象如果有個(gè)閉包。當(dāng)這個(gè)閉包是個(gè)內(nèi)部函數(shù),是用來(lái)外部函數(shù)中創(chuàng)建的變量,然后這個(gè)內(nèi)部函數(shù)被返回到了外面。這就意味著激活對(duì)象不應(yīng)該存在棧中,而是堆中(動(dòng)態(tài)分配內(nèi)存)。它會(huì)一直被保存,當(dāng)閉包的引用使用激活對(duì)象中的變量。更重要的是,不僅是一個(gè)激活對(duì)象被保存,如果需要,所有的父級(jí)的激活對(duì)象。

var bar = (function foo() {
  var x = 10;
  var y = 20;
  return function bar() {
    return x + y;
  };
})();
 
bar(); // 30

如果foo函數(shù)創(chuàng)建了一個(gè)閉包,即使foo執(zhí)行結(jié)束了,它的幀不會(huì)從內(nèi)存中移除,因?yàn)殚]包中有它的引用。

環(huán)境幀模型

和c不同,ECMAScript含有內(nèi)部函數(shù)和閉包。此外,所有的函數(shù)是一等公民。

一等函數(shù)

一等函數(shù)被當(dāng)作普通的對(duì)象,可以被作為參數(shù),可以作為返回值。一個(gè)簡(jiǎn)單的例子

// create a function expression
// dynamically at runtime and
// bind it to "foo" identifier
 
var foo = function () {
  console.log("foo");
};
 
// pass it to another function,
// which in turn is also created
// at runtime and called immediately
// right after the creation; result
// of this function is again bound
// to the "foo" identifier
 
foo = (function (funArg) {
 
  // activate the "foo" function
  funArg(); // "foo"
 
  // and return it back as a value
  return funArg;
 
})(foo);
函數(shù)參數(shù)和高階函數(shù)

當(dāng)一個(gè)函數(shù)被作為參數(shù),稱(chēng)之為“funarg”-- functional argument的縮寫(xiě)。將函數(shù)作為參數(shù)的函數(shù)稱(chēng)為高階函數(shù)(higher-order function),和數(shù)學(xué)上的算子概念相似。

自由變量

自由變量是函數(shù)中使用的變量,既不是函數(shù)的參數(shù),也不是函數(shù)的本地變量。換句話說(shuō),自由變量并不存在自身的環(huán)境中,而是周?chē)沫h(huán)境中。

// Global environment (GE)
 
var x = 10;
 
function foo(y) {
 
  // environment of "foo" function (E1)
 
  var z = 30;
 
  function bar(q) {
    // environment of "bar" function (E2)
    return x + y + z + q;
  }
 
  // return "bar" to the outside
  return bar;
 
}
 
var bar = foo(20);
 
bar(40); // 100

在這個(gè)例子中,我們有三個(gè)環(huán)境:GE,E1和E2,分別對(duì)應(yīng)于全局對(duì)象,foo函數(shù)和bar函數(shù)。因此,對(duì)于bar函數(shù)來(lái)說(shuō),變量x,y,z是自由變量,它們既不是函數(shù)參數(shù),也不是bar的本地變量。值得注意的是,foo函數(shù)并沒(méi)有用到自由變量。但是變量x在內(nèi)部的bar函數(shù)中被使用,另外在foo函數(shù)運(yùn)行的過(guò)程中創(chuàng)建bar函數(shù),盡管如此,還是保存了父環(huán)境的綁定,為了能夠?qū)的綁定傳遞給內(nèi)部嵌套的函數(shù)。正確的并期望出現(xiàn)100,當(dāng)執(zhí)行bar函數(shù)后,這意味著bar函數(shù)記住了foo函數(shù)激活時(shí)的環(huán)境,即使foo函數(shù)已經(jīng)結(jié)束了。這就是與基于棧的激活記錄模型的不同。當(dāng)我們?cè)试S內(nèi)部函數(shù),同時(shí)希望靜態(tài)詞法作用域,同時(shí)將函數(shù)作為一等公民,我們應(yīng)該保存函數(shù)需要的所有自由變量,當(dāng)函數(shù)被創(chuàng)建的時(shí)候。

環(huán)境定義

最直接最簡(jiǎn)單的方法去實(shí)現(xiàn)這樣的算法是保存完整的父環(huán)境,在這個(gè)父環(huán)境中,函數(shù)被創(chuàng)建。然后,在函數(shù)自己執(zhí)行時(shí),我們創(chuàng)建自己的環(huán)境,保存自己的本地變量和參數(shù),然后設(shè)置我們的外部環(huán)境為之前保存的那個(gè),為了能夠在那找到自由變量。我們用術(shù)語(yǔ)環(huán)境指代多帶帶綁定對(duì)象,或者所有的綁定對(duì)象依據(jù)嵌套的深度。在后面的情形中,我們將綁定對(duì)象稱(chēng)為環(huán)境幀。一個(gè)環(huán)境是一些列幀,每個(gè)幀是個(gè)記錄綁定,將變量名和值關(guān)聯(lián)起來(lái)。我們用抽象的概念記錄,而沒(méi)有具體說(shuō)明它的實(shí)現(xiàn)結(jié)構(gòu),它可能是堆中的哈希表,棧內(nèi)存,虛擬機(jī)注冊(cè)(registers of the virtual machine)等。例如,例子中,環(huán)境E2有三個(gè)幀:自己的bar,foo的和全局的。環(huán)境E1有兩個(gè)幀:foo自己的,和全局的。全局環(huán)境GE只有一個(gè)幀:全局。

一個(gè)幀中任何變量至多只有一個(gè)綁定。每個(gè)幀都有個(gè)指針,指向圍繞它的環(huán)境。全局幀的外部環(huán)境的鏈接是null。變量相對(duì)于環(huán)境的值是在包含該變量的綁定的環(huán)境中的第一幀中的變量的綁定給出的值(The value of a variable with respect to an environment is the value given by the binding of the variable in the first frame in the environment that contains a binding for that variable)(源自谷歌翻譯)。

var x = 10;
 
(function foo(y) {
   
  // use of free-bound "x" variable
  console.log(x);
 
  // own-bound "y" variable
  console.log(y); // 20
   
  // and free-unbound variable "z"
  console.log(z); // ReferenceError: "z" is not defined
 
})(20);

一系列的環(huán)境幀形成了我們所稱(chēng)的作用域鏈。一個(gè)環(huán)境可能會(huì)包裹多個(gè)內(nèi)部環(huán)境。

// Global environment (GE)
 
var x = 10;
 
function foo() {
 
  // "foo" environment (E1)
 
  var x = 20;
  var y = 30;
 
  console.log(x + y);
 
}
 
function bar() {
   
  // "bar" environment (E2)
 
  var z = 40;
 
  console.log(x + z);
}

偽代碼

// global
GE = {
  x: 10,
  outer: null
};
 
// foo
E1 = {
  x: 20,
  y: 30,
  outer: GE
};
 
// bar
E2 = {
  z: 40,
  outer: GE
};

變量x相對(duì)于環(huán)境E1的綁定遮蔽了同名變量在全局環(huán)境中的綁定。

函數(shù)創(chuàng)建和應(yīng)用法則

一個(gè)函數(shù)是相對(duì)于給定的環(huán)境創(chuàng)建的。這導(dǎo)致函數(shù)對(duì)象是由函數(shù)本身的代碼(函數(shù)體)和指向創(chuàng)建函數(shù)本身的環(huán)境的指針構(gòu)成。

// global "x"
var x = 10;
 
// function "foo" is created relatively
// to the global environment
 
function foo(y) {
  var z = 30;
  console.log(x + y + z);
}

相當(dāng)于偽代碼

// create "foo" function
 
foo = functionObject {
  code: "console.log(x + y + z);"
  environment: {x: 10, outer: null}
};

注意,函數(shù)指向它的環(huán)境,其中一個(gè)環(huán)境與函數(shù)自身相綁定。一個(gè)函數(shù)被調(diào)用,一系列的參數(shù)構(gòu)成了新的幀,在這個(gè)幀中綁定了本地變量,然后在創(chuàng)建的新的環(huán)境中執(zhí)行函數(shù)體。

// function "foo" is applied
// to the argument 20
 
foo(20);

與之對(duì)應(yīng)的偽代碼

// create a new frame with formal 
// parameters and local variables
 
fooFrame = {
  y: 20,
  z: 30,
  outer: foo.environment
};
 
// and evaluate the code
// of the "foo" function 
 
execute(foo.code, fooFrame); // 60

閉包

閉包是由函數(shù)代碼和創(chuàng)建函數(shù)的環(huán)境構(gòu)成的。閉包被發(fā)明用來(lái)解決函數(shù)參數(shù)的問(wèn)題。

函數(shù)參數(shù)問(wèn)題

當(dāng)返回一個(gè)函數(shù)到外面,這個(gè)函數(shù)使用了創(chuàng)建它的父環(huán)境中的自由變量怎么辦?

(function (x) {
  return function (y) {
    return x + y;
  };
})(10)(20); // 30

正如我們所知,詞法作用域在堆中保存封閉的幀。這是問(wèn)題的關(guān)鍵。像c一樣用棧來(lái)保存綁定是不可行的。被保存的代碼塊和環(huán)境就是個(gè)閉包。當(dāng)我們把函數(shù)作為參數(shù)傳遞到其他函數(shù)中,這個(gè)函數(shù)參數(shù)中的自由變量是如何被解析的,是在函數(shù)定義的作用域中,還是函數(shù)執(zhí)行的作用域中?

var x = 10;
 
(function (funArg) {
 
  var x = 20;
  funArg(); // 10, not 20
 
})(function () { // create and pass a funarg
  console.log(x);
});

回答這個(gè)問(wèn)題的關(guān)鍵就是詞法作用域。

組合環(huán)境幀模型

很明顯,如果一些變量不被內(nèi)部函數(shù)需要,就沒(méi)有必要保存它們。

// global environment
 
var x = 10;
var y = 20;
 
function foo(z) {
 
  // environment of "foo" function
  var q = 40;
 
  function bar() {
    // environment of "bar" function
    return x + z;
  }
 
  return bar;
 
}
 
// creation of "bar"
var bar = foo(30);
 
// applying of "bar"
bar();

沒(méi)有函數(shù)使用變量y,因此,我們不需要在foo和bar的閉包中保存它。全局變量x沒(méi)有在函數(shù)foo中使用,但是我們?nèi)詰?yīng)該保存它,因?yàn)楦畹膬?nèi)部函數(shù)bar需要它。

bar = closure {
  code: <...>,
  environment: {
    x: 10,
    z: 30,
  }
}

[譯者注:后面是python等其他語(yǔ)言閉包的例子,不譯了]

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/89602.html

相關(guān)文章

  • JavaScript 進(jìn)階 從實(shí)現(xiàn)理解閉包(校對(duì)版)

    摘要:嵌套函數(shù)在一個(gè)函數(shù)中創(chuàng)建另一個(gè)函數(shù),稱(chēng)為嵌套。這在很容易實(shí)現(xiàn)嵌套函數(shù)可以訪問(wèn)外部變量,幫助我們很方便地返回組合后的全名。更有趣的是,嵌套函數(shù)可以作為一個(gè)新對(duì)象的屬性或者自己本身被。 來(lái)源于 現(xiàn)代JavaScript教程閉包章節(jié)中文翻譯計(jì)劃本文很清晰地解釋了閉包是什么,以及閉包如何產(chǎn)生,相信你看完也會(huì)有所收獲 關(guān)鍵字Closure 閉包Lexical Environment 詞法環(huán)境En...

    wuyangnju 評(píng)論0 收藏0
  • Lexical environments: ECMAScript implementation

    摘要:全局環(huán)境是作用域鏈的終點(diǎn)。環(huán)境記錄類(lèi)型定義了兩種環(huán)境記錄類(lèi)型聲明式環(huán)境記錄和對(duì)象環(huán)境記錄聲明式環(huán)境記錄聲明式環(huán)境記錄是用來(lái)處理函數(shù)作用域中出現(xiàn)的變量,函數(shù),形參等。變量環(huán)境變量環(huán)境就是存儲(chǔ)上下文中的變量和函數(shù)的。解析的過(guò)程如下 原文 ECMA-262-5 in detail. Chapter 3.2. Lexical environments: ECMAScript implement...

    roadtogeek 評(píng)論0 收藏0
  • 談?wù)凧avascript中的delete操作符

    摘要:你覺(jué)得下列代碼中,哪些操作能成功人肉判斷一下,不要放進(jìn)瀏覽器里執(zhí)行。故對(duì)于解析而言,得到的為上述所有的屬性在下均為。那么又有什么玄機(jī)呢的操作可理解為對(duì)于,調(diào)用其內(nèi)部的方法。幾乎所有的都是不可刪除的。 你覺(jué)得下列代碼中,哪些delete操作能成功?人肉判斷一下,不要放進(jìn)瀏覽器里執(zhí)行。 // #1 a = hello world; delete a; // #2 var b = hel...

    antz 評(píng)論0 收藏0
  • 溫故而知新:JS 變量提升與時(shí)間死區(qū)

    摘要:這意味著引擎在源代碼中聲明它的位置計(jì)算其值之前,你無(wú)法訪問(wèn)該變量。因此它們同樣會(huì)受到時(shí)間死區(qū)的影響。正確理解提升機(jī)制將有助于避免因變量提升而產(chǎn)生的任何未來(lái)錯(cuò)誤和混亂。 開(kāi)始執(zhí)行腳本時(shí),執(zhí)行腳本的第一步是編譯代碼,然后再開(kāi)始執(zhí)行代碼,如圖 showImg(https://segmentfault.com/img/bVbnPrh?w=1233&h=141); 另外,在編譯優(yōu)化方面來(lái)說(shuō),最開(kāi)...

    codecraft 評(píng)論0 收藏0
  • [譯] 透過(guò)重新實(shí)作來(lái)學(xué)習(xí)參透閉包

    摘要:不過(guò)到底是怎麼保留的另外為什麼一個(gè)閉包可以一直使用區(qū)域變數(shù),即便這些變數(shù)在該內(nèi)已經(jīng)不存在了為了解開(kāi)閉包的神秘面紗,我們將要假裝沒(méi)有閉包這東西而且也不能夠用嵌套來(lái)重新實(shí)作閉包。 原文出處: 連結(jié) 話說(shuō)網(wǎng)路上有很多文章在探討閉包(Closures)時(shí)大多都是簡(jiǎn)單的帶過(guò)。大多的都將閉包的定義濃縮成一句簡(jiǎn)單的解釋?zhuān)蔷褪且粋€(gè)閉包是一個(gè)函數(shù)能夠保留其建立時(shí)的執(zhí)行環(huán)境。不過(guò)到底是怎麼保留的? 另外...

    CoXie 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<