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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何“遞歸地”將調(diào)用其他作用域函數(shù)的 javascript 函數(shù)字符串化?

如何“遞歸地”將調(diào)用其他作用域函數(shù)的 javascript 函數(shù)字符串化?

Helenr 2021-12-12 16:09:21
因?yàn)?javascript 函數(shù)是不可序列化的,為了有時(shí)(盡管很少)將它們傳遞到新的上下文中,將它們字符串化然后稍后重新評(píng)估它們會(huì)很有用,例如:const foo = () => { // do something }const fooText = foo.toString()// later... in new context & scopeconst fooFunc = new Function(' return (' + fooText + ').apply(null, arguments)')fooFunc() // works!但是,如果foo引用另一個(gè) function bar,則范圍未字符串化,因此如果bar未在新上下文中定義,則評(píng)估的 foo 函數(shù)將在調(diào)用時(shí)拋出錯(cuò)誤。我想知道是否有辦法遞歸地對(duì)函數(shù)進(jìn)行字符串化?也就是說(shuō),不僅將父函數(shù)字符串化,還要將父函數(shù)調(diào)用的子函數(shù)的內(nèi)容字符串化。例如:let bar = () => { alert(1) }let foo = () => { bar() }// what toString doeslet fooString = foo.toString()console.log(fooString) // "() => { bar() }"// what we wantlet recursiveFooString = foo.recursiveToString()console.log(recursiveFooString) // "() => { alert(1) }"如果您對(duì)如何完成諸如“recursiveToString”之類的事情有任何想法,請(qǐng)告訴我
查看完整描述

3 回答

?
手掌心

TA貢獻(xiàn)1942條經(jīng)驗(yàn) 獲得超3個(gè)贊

做到這一點(diǎn)的唯一好方法是從包含所有函數(shù)foo最終引用的父作用域開(kāi)始。例如,對(duì)于您的fooand bar,如果您想傳遞foo到另一個(gè)bar可調(diào)用的上下文中,請(qǐng)傳遞一個(gè)同時(shí)聲明fooandbar并返回的函數(shù)foo。例如:


const makeFoo = () => {

  let bar = () => { alert(1) }

  let foo = () => { bar() }

  return foo;

};

const makeFooStr = makeFoo.toString();


// ...


const makeFooFunc = new Function(' return (' + makeFooStr + ').apply(null, arguments)');

const foo = makeFooFunc();

foo();


很好地實(shí)現(xiàn)這類事情確實(shí)需要像上面那樣有預(yù)謀的設(shè)計(jì)(不幸的是)。在字符串化時(shí),您不能真正包含所有祖先 LexicalEnvironments(變量名稱到給定范圍內(nèi)的值的內(nèi)部映射)。


查看完整回答
反對(duì) 回復(fù) 2021-12-12
?
jeck貓

TA貢獻(xiàn)1909條經(jīng)驗(yàn) 獲得超7個(gè)贊

我想知道是否有辦法遞歸地對(duì)函數(shù)進(jìn)行字符串化?


我認(rèn)為我們可以相當(dāng)簡(jiǎn)單地證明這在一般情況下是不可能的。


讓我們想想這兩個(gè)函數(shù)


const greet = (greeting) => (name) => `${greeting} ${name}`

const sayHi = greet ('Hi') 


sayHi ('Jane') //=> "Hi Jane"

雖然你foo和bar例子,我們可能想象的東西,審查的功能,在當(dāng)前范圍內(nèi)做基于解析功能,并知道什么實(shí)際使用的局部變量的擴(kuò)展功能字符串化使用提供一切的身體。(我猜這也是不可能的,原因與賴斯定理有關(guān),但我們當(dāng)然可以想象。)


但在這里,請(qǐng)注意


sayHi.toString() //=> "(name) => `${greeting} ${name}`"

因此sayHi取決于一個(gè)未存儲(chǔ)在我們當(dāng)前作用域中的自由變量,即greeting. 我們只是沒(méi)有在任何地方存儲(chǔ)用于創(chuàng)建該函數(shù)的“Hi”,除了在 的閉包范圍內(nèi)sayHi,它沒(méi)有在任何地方公開(kāi)。


所以即使是這個(gè)簡(jiǎn)單的函數(shù)也不能可靠地序列化;對(duì)更復(fù)雜的事情似乎沒(méi)有希望。


查看完整回答
反對(duì) 回復(fù) 2021-12-12
?
波斯汪

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個(gè)贊

我最終滾動(dòng)的靈感來(lái)自@CertainPerformance 的回答。


訣竅是構(gòu)建一個(gè)定義所有子被調(diào)用函數(shù)的函數(shù)。然后你就擁有了字符串化父函數(shù)所需的一切。


注意:為了允許從其他文件導(dǎo)入被調(diào)用函數(shù),我決定用被調(diào)用定義以編程方式構(gòu)建一個(gè)字符串,而不是最初在同一范圍內(nèi)定義它們。


代碼:

    // original function definitions (could be in another file)

    let bar = () => { alert(1) }

    let foo = () => { bar() }



    const allCallees = [ bar, foo ] 


    // build string of callee definitions

    const calleeDefinitions = allCallees.reduce(

      (definitionsString, callee) => {

        return `${definitionsString} \n const ${callee.name} = ${callee.toString()};`;

      }, 

      "",

    );


    // wrap the definitions in a function that calls foo

    const fooString = `() => { ${calleeDefinitions} \n return foo(); \n }`;


    console.log(fooString);

    /** 

     * fooString looks like this:

     * `() => {  

     *    const bar = () => { alert(1) }; 

     *    const foo = () => { bar() }; 

     *    return foo();

     *  }`

    **/ 

     


    // in new context & scope

    const evaluatedFoo = new Function(' return (' + fooString + ').apply(null, arguments)');


    // works as expected

    evaluatedFoo();


查看完整回答
反對(duì) 回復(fù) 2021-12-12
  • 3 回答
  • 0 關(guān)注
  • 169 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)