多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > 互聯(lián)網(wǎng) > Effective JavaScript Item 29 避免使用非規(guī)范的Stack Inspection屬性

Effective JavaScript Item 29 避免使用非規(guī)范的Stack Inspection屬性

來(lái)源:程序員人生   發(fā)布時(shí)間:2014-10-03 08:00:00 閱讀次數(shù):1893次

本系列作為Effective JavaScript的讀書筆記。

 

由于歷史原因,很多JavaScript執(zhí)行環(huán)境中都提供了某些方式來(lái)查看函數(shù)調(diào)用棧。在一些環(huán)境中,arguments對(duì)象(關(guān)于該對(duì)象可以查看Item 222324)上有兩個(gè)額外的屬性:

 

arguments.callee - 它引用了正在被調(diào)用的函數(shù)

arguments.caller - 它引用了調(diào)用當(dāng)前函數(shù)的函數(shù)

 

關(guān)于arguments.callee的使用,可以參考下面的代碼:


var factorial = (function(n) { return (n <= 1) ? 1 : (n * arguments.callee(n - 1)); });

可見,在遞歸函數(shù)中,可以使用callee來(lái)得到當(dāng)前正在被調(diào)用的函數(shù)。

 

但是,使用函數(shù)聲明的方式也可以很方便的實(shí)現(xiàn)函數(shù)的遞歸調(diào)用,并且這種方式更加清晰:


function factorial(n) { return (n <= 1) ? 1 : (n * factorial(n - 1)); }

而對(duì)于arguments.caller,它提供的功能就更加強(qiáng)大了,能保存了調(diào)用當(dāng)前函數(shù)的函數(shù)的一個(gè)引用。因?yàn)樗邪踩[患,所以很多JavaScript運(yùn)行環(huán)境都將這個(gè)屬性移除了。同時(shí),有部分運(yùn)行環(huán)境在函數(shù)對(duì)象上提供了一個(gè)caller屬性來(lái)達(dá)到和arguments.caller相同的效果:


function revealCaller() { return revealCaller.caller; } function start() { return revealCaller(); } start() === start; // true

因此,可以利用這個(gè)屬性來(lái)得到當(dāng)前調(diào)用棧的信息:


function getCallStack() { var stack = []; for (var f = getCallStack.caller; f; f = f.caller) { stack.push(f); } return stack; }

對(duì)于簡(jiǎn)單的調(diào)用關(guān)系,上述確實(shí)能夠得到調(diào)用棧的信息:


function f1() { return getCallStack(); } function f2() { return f1(); } var trace = f2(); trace; // [f1, f2]

但是當(dāng)一個(gè)函數(shù)在調(diào)用棧中出現(xiàn)不止一次時(shí),就會(huì)發(fā)生問(wèn)題了,比如下面的代碼會(huì)產(chǎn)生一個(gè)死循環(huán):


function f(n) { return n === 0 ? getCallStack() : f(n - 1); } var trace = f(1); // infinite loop

原因在于,當(dāng)發(fā)生遞歸調(diào)用時(shí),函數(shù)自身會(huì)被賦值給它的caller屬性。因此getCallStack中的for循環(huán)的終止條件f永遠(yuǎn)不會(huì)為false


for (var f = getCallStack.caller; f; f = f.caller) { stack.push(f); }

正因?yàn)檫@種不穩(wěn)定性和由此帶來(lái)的安全性問(wèn)題,在ES5strict mode中,使用caller或者callee屬性都是被禁止的:


function f() { "use strict"; return f.caller; } f(); // error: caller may not be accessed on strict functions

總結(jié):

  1. 避免使用arguments對(duì)象上的calleecaller屬性。
  2. 避免使用function對(duì)象上的caller屬性。


生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 一本大道香蕉中文日本不卡高清二区 | 乌克兰性欧美精品高清bd | 伊人网亚洲| 午夜写真福利视频在线观看 | 久久男人的天堂 | 中文在线日本免费永久18近 | 久久精品在 | 91亚洲精品成人一区 | 99爱免费观看视频在线 | 中文字幕精品一区二区精品 | 国产亚洲精品国产 | 精品欧美一区二区三区四区 | 中文字幕在线播放第一页 | 精品午夜寂寞黄网站在线 | 国产精品天天看天天爽 | 国产成在线观看免费视频成本人 | 在线婷婷 | 特级aa毛片在线播放 | 久久久久一区二区三区 | 无遮挡在线视频 | 欧美h版成版在线观看 | www.爽 | 天天综合天天做天天综合 | 伊人免费在线观看 | 国产精品亚洲综合五月天 | 久久久久久久99视频 | 五月天婷婷一区二区三区久久 | 日本不卡一区二区三区四区 | 欧美三级在线看 | 米奇影院日韩免费 | 色老成人精品视频在线观看 | 亚洲蜜桃| 欧美一区二区三区免费 | 国产精品久久久久久久久免费hd | 波多野结衣在线观看免费区 | 日本精品a在线 | 午夜精品久久久久久久第一页 | 香蕉视频在线网址 | 亚洲精品国产成人一区二区 | 午夜在线精品不卡国产 | 伊人久久大香线蕉亚洲 |