第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么以下兩個例子執(zhí)行結果不同?

為什么以下兩個例子執(zhí)行結果不同?

一只萌萌小番薯 2019-03-07 18:15:03
var x = 1;function foo(x, y = function() { x = 2; }) {  var x = 3;  y();  console.log(x);}foo() // 3x // 1而去掉var以后:var x = 1;function foo(x, y = function() { x = 2; }) {  x = 3;  y();  console.log(x);}foo() // 2x // 1為什么實例一的y執(zhí)行完成沒有改變任何x的值?而去掉var輸出結果就會改變?
查看完整描述

4 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

函數聲明時設置的默認參數值是在函數調用時計算賦值的,而不是在函數聲明時賦值


我們可以看下下面的例子


function foo2(a, b = (function() { console.log(c); return function(){} })()) {

    b();

}

foo2();

調用 foo2();

控制臺將輸出:

Uncaught ReferenceError: c is not defined


at b (<anonymous>:1:47)

at foo2 (<anonymous>:2:5)

at <anonymous>:1:1

而不掉用 foo2();

控制臺將不報錯


以上例子說明了函數參數的默認值是在調用是賦值的,而不是在聲明時。


對于問題的代碼,還有注意一點,y默認值函數聲明中的x是綁定為函數聲明中的參數x變量而不是foo外層作用域中的變量x


function foo(x, y = function() { x = 2; }) {

  console.log("x1:"+x);

  y();

  console.log("x2:"+x);

}

foo();

輸出 

x1:undefined

x2:2


那么下面的代碼輸出2就好理解了


var x = 1;

function foo(x, y = function() { x = 2; }) {

  x = 3;

  y();

  console.log(x);

}


foo(); // 2


查看完整回答
反對 回復 2019-03-18
?
慕娘9325324

TA貢獻1783條經驗 獲得超4個贊

看到了很多答案,在大家的提示下 我去查了很多資料現在已經理解了這個結果。


var x = 1;

function foo(x, y = function() { x = 2; }) {

  var x = 3;

  y();

  console.log(x);

}


foo() // 3

x // 1

以上的代碼 作用域鏈如下:

https://img1.sycdn.imooc.com//5c8f44bc00011d1608000636.jpg

以上的圖涉及一個問題,那就是為什么foo的參數居然是自成一個作用域鏈?

這是因為es6規(guī)定:

一旦設置了參數的默認值,函數進行聲明初始化時,參數會形成一個單獨的作用域(context)。等到初始化結束,這個作用域就會消失。這種語法行為,在不設置參數默認值時,是不會出現的。

也就是說y中的x=2,因為y中是沒有x變量的,所以向上一級查找,他的上一級就是傳入的參數x,因此y函數的作用改變的是參數x

而當foo內部var x=3時,這時內部的x已經覆蓋掉了參數x,

console.log查找的是它的上一層foo的內部變量作用域x,這個x是等于3的,因此foo執(zhí)行為3,一下貼出作用域鏈的一個概念,覺得解釋的非常好

作用域鏈:作用域鏈是一個對象列表或者鏈表,這組對象定義了這段代碼’作用關于中’的變量。當javascript需要查找變量x的值得時候(變量解析),他會從鏈中的第一個對象開始查找,如果這個對象有一個名為x的屬性,則會直接使用這個屬性的值,如果第一個對象中不存在名為x的屬性,javascript會繼續(xù)查找鏈上的下一個對象。如果第二個對象依然沒有名為x的屬性,則會繼續(xù)查找下一個對象,以此類推。如果作用域鏈上沒有任何一個對象含有屬性x,那么久認為這段代碼的作用域鏈上不存在x,并最終爆出一個引用錯誤異常。(犀牛書P59)


而第二段代碼:


var x = 1;

function foo(x, y = function() { x = 2; }) {

  x = 3;

  y();

  console.log(x);

}


foo() // 2

x // 1

作用域鏈如下:

https://img1.sycdn.imooc.com//5c8f44c900019da808000656.jpg

foo中的console.log(x)中的x會查到他的上一級傳入的參數x,因為傳入的參數被y函數改為2,所以輸出2
而第一個例子中的x上一級作用域鏈直接是新定義的x=3所以輸出3

查看完整回答
反對 回復 2019-03-18
  • 4 回答
  • 0 關注
  • 546 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號