日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

[Effective JavaScript 笔记]第29条:避免使用非标准的栈检查属性

發布時間:2025/3/15 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Effective JavaScript 笔记]第29条:避免使用非标准的栈检查属性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

許多js環境都提供檢查調用棧的功能。調用棧是指當前正在執行的活動函數鏈。在某些舊的宿主環境中,每個arguments對象含有兩個額外的屬性:arguments.callee和arguments.caller。前者指向使用該arguments對象被調用的函數。后者指向調用該arguments對象被調用的函數的函數。許多環境支持arguments.callee,但它除了允許匿名函數遞歸地引用自身之外,沒有更多的用途了。(高3中認為使用arguments.callee可以解除函數體內的代碼和函數名之間的耦合,看來也不是完全沒有用的)

圖示

下面是一個簡單的圖示,可以容易了解arguments的callee,caller,及函數的caller

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

但這個也是特別的有用,可以使用函數名來引用函數自身

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

arguments.caller屬性更為強大。它指向的是使用該arguments對象調用函數的函數。出于安全考慮,大多數環境已經移除了此特性,因此用它時要檢測一下才行。許多JS環境也提供了一個相似的函數對象屬性--非標準但普遍適應的caller屬性。它指向函數最近的調用者。

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

可以利用該屬性獲取一個提供當前調用棧快照的數據結構。構建一個棧跟蹤:

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

使用示例

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

脆弱性,當某個函數在調用棧中出現不止一次,那么棧檢查邏輯將會陷入循環。

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

問題出在哪?由于函數f遞歸地調用其自身,因此其caller屬性會自動更新,指回到函數f。所以,函數getCallStack會陷入無限地查找函數f的循環之中。即使我們試圖檢測該循環,但在函數f調用其自身之前也沒有關于哪個函數調用了它的信息。因為其他調用棧的信息已經丟失了。
這些棧檢查屬性都是非標準的,在移植性或適用性上很受限制。在ES5的嚴格模式的函數中,它們是被禁止使用的。試圖獲取嚴格函數或arguments對象的caller或callee屬性都將報錯。

function f(){'use strict';return f.caller; } f();//Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.(…)

最好的策略是完全避免棧檢查。如果檢查棧的理由完全是為了測試,那么更為可靠的方式是使用交互式的調試器。

提示

  • 避免使用非標準的arguments.caller和arguments.callee屬性,它們不具備良好的移植性

  • 避免使用非標準的函數對象caller屬性,因為在包含全部棧信息方面,它是不可靠的

附錄:這個沒附錄,放水一篇,因為這節實在沒什么可寫的。

轉載于:https://www.cnblogs.com/wengxuesong/p/5570821.html

總結

以上是生活随笔為你收集整理的[Effective JavaScript 笔记]第29条:避免使用非标准的栈检查属性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。