最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js執(zhí)行字符串代碼的具體實現(xiàn)

 更新時間:2024年06月14日 10:09:56   作者:程序員的脫發(fā)之路  
這篇文章主要給大家介紹了js執(zhí)行字符串代碼的具體實現(xiàn),需要的朋友可以參考下

一、適用場景

在業(yè)務(wù)中我們很少去將一個字符串作為代碼執(zhí)行,因為出于安全考慮,盡量不要直接在客戶端執(zhí)行用戶輸入的代碼。但是在造輪子或者框架開發(fā)中,我們需要在解析完開發(fā)者編寫的代碼后,來手動執(zhí)行這些字符串代碼。

二、具體實現(xiàn)

1. eval

eval是一個我們都知道的函數(shù),這個函數(shù)會將傳入的字符串當(dāng)做 JavaScript 代碼進(jìn)行執(zhí)行。所以我們很多時候會用它來執(zhí)行字符串代碼。

例如:

  const log = `console.log('11')`
  eval(log)
  const testCode = `
  function test() {
    console.log('test')
  }
  test()
  `
  eval(testCode)

注:需要注意的是,eval是在當(dāng)前上下文執(zhí)行的代碼,如果字符串中的變量與當(dāng)前上下文的變量命名沖突,就會導(dǎo)致報錯。

例如:

  const test = 'test'
  const testCode = `
  function test() {
    console.log('test')
  }
  test()
  `
  eval(testCode)

因為我們自己定義了test,而字符串中又有test函數(shù),所以就發(fā)生了沖突,出現(xiàn)報錯。

我們很難去避免字符串中的變量和當(dāng)前上下文的變量重復(fù),所以我們可以在自調(diào)用函數(shù)中執(zhí)行eval來解決這個問題。

  const test = 'test'
  const a = 1
  const testCode = `
  function test() {
    console.log('test')
    console.log(a)
  }
  test()
  `
  ;(function () {
    const a = 2
    eval(testCode)
  })()

這樣就沒問題了,注:這里的a打印的是2,也就是我們自調(diào)用函數(shù)作用域的a。

2. new Function()

語法:new Function(arg0, arg1, /* …, */ argN, functionBody)Function() 構(gòu)造函數(shù)創(chuàng)建 Function 對象。直接調(diào)用構(gòu)造函數(shù)可以動態(tài)創(chuàng)建函數(shù),但可能會面臨一些安全性和類似于 eval() 的性能問題(但相對較?。?。然而,與具有訪問本地作用域的 eval 不同,F(xiàn)unction 構(gòu)造函數(shù)創(chuàng)建的函數(shù)僅在全局作用域中執(zhí)行。

例如:

  const test = 'test'
  const a = 1
  const testCode = `
  function test() {
    console.log('test')
    console.log(a)
  }
  test()
  `
  ;(function () {
    const a = 2
    const func = new Function(testCode)
    func()
  })()

注:當(dāng)前的a打印的是1,也就是Function 構(gòu)造函數(shù)創(chuàng)建的函數(shù)僅在全局作用域中執(zhí)行。里面的未定義的變量會直接使用全局的變量。

如何解決這個問題?

創(chuàng)建function的時候支持傳遞參數(shù),我們可以通過參數(shù)傳遞來解決。

  const test = 'test'
  const a = 1
  const testCode = `
  function test() {
    console.log('test')
    console.log(a)
  }
  test()
  `
  ;(function () {
    const a = 2
    const func = new Function('a', testCode)
    func(a)
  })()

我們將a傳遞作為參數(shù)傳遞到了func中,實際上func現(xiàn)在就相當(dāng)于:

  function func(a) {
    function test() {
      console.log('test')
      console.log(a)
    }
    test()
  }

這種方式就不用但是上下文命名沖突的問題,因為代碼是在函數(shù)中執(zhí)行的,因此我們不需要在自調(diào)用函數(shù)中運(yùn)行 new Function()。
并且通過這種方式我們還能接受到字符串代碼中的返回。

  const test = 'test'
  const sum = `return a + b`
  const func = new Function('a', 'b', sum)
  console.log(func(2, 3))

三、兩者差異

  • eval是在當(dāng)前上下文執(zhí)行代碼,會出現(xiàn)變量命名沖突,而new Function()是在函數(shù)內(nèi)部執(zhí)行,不會出現(xiàn)沖突
  • eval的作用域是當(dāng)前執(zhí)行位置的作用域,而new Function()的作用域是全局
  • eval不能傳遞參數(shù),也不能接受返回值,new Function()可以傳遞參數(shù)并接收返回值
    所以如果是大量的執(zhí)行字符串代碼,建議使用new Function()的方式,它更強(qiáng)大(比如Vue框架就使用new Function()的方式)。如果你只是偶爾使用,并且對參數(shù)、命名也沒要求,那就直接使用eval,更加簡單方便。

附:結(jié)合eval和new Function()一起實現(xiàn)

try {
const val = new Function(“要執(zhí)行的字符串”);
let eleResult = val(); // 這里必須調(diào)用val(),不然不會執(zhí)行
if (!eleResult) {
eleResult = eval(“要執(zhí)行的字符串”);
}
} catch (err) {
console.info(‘執(zhí)行字符串js出錯');
}

到此這篇關(guān)于js執(zhí)行字符串代碼具體實現(xiàn)的文章就介紹到這了,更多相關(guān)js執(zhí)行字符串代碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

体育| 临武县| 屯留县| 门源| 青冈县| 华蓥市| 孟村| 信宜市| 朝阳市| 全南县| 金山区| 岳阳市| 大邑县| 泰和县| 永春县| 昌黎县| 来凤县| 廊坊市| 宁蒗| 阜新市| 延川县| 荔波县| 濮阳市| 都江堰市| 峨山| 报价| 大安市| 晋中市| 抚宁县| 廉江市| 蓬安县| 灵武市| 噶尔县| 泰顺县| 益阳市| 萝北县| 鄂伦春自治旗| 梅州市| 沅陵县| 游戏| 盐边县|