JavaScript 全局函数 eval() 详解

🌙
手机阅读
本文目录结构

功能

eval() 的参数是一个字符串,函数会将传入的字符串当做 JavaScript 代码进行执行。

例子

console.log(eval('2 + 2'));//4

console.log(eval('(2 + 2)===4'));//true
console.log(eval('2 + 2') === eval('4'));//true

注意

很多人被一些教程和培训老师恐吓的,提到eval就像提到魔鬼一样,其实大可不必;

eval只是因为功能太过变态,权限很高;我们尽量不要用这个方法处理用户传入的数据,在编程的时候,后端永远不要相信前端的数据,前端永远不好相信用户的数据,因为我们永远不能相信用户传入的时候,所以 eval 可能会带来未知的隐患,这方面确实要注意。

永远不要相信用户传入的数据,永远不要把 eval 用于处理用户传入的数据

但是因为它的功能很好,还有一些不错的用法,可以用在实际项目中;

eval 在实际项目中的使用

如果符合某条件,import对应的文件

下面是 jquery 项目的,一段代码

https://github.com/jquery/jquery/blob/437f389a24a6bef213d4df507909e7e69062300b/test/jquery.js

// 如果符合某个条件
if ( config.esmodules && QUnit ) {
    // Support: IE 11+, Edge 12 - 18+
    // IE/Edge don't support the dynamic import syntax so they'd crash
    // with a SyntaxError here.
    dynamicImportSource = "" +
        "import( `${ parentUrl }src/jquery.js` )\n" +
        "	.then( ( { default: jQuery } ) => {\n" +
        "		window.jQuery = jQuery;\n" +
        "		if ( typeof loadTests === \"function\" ) {\n" +
        "			// Include tests if specified\n" +
        "			loadTests();\n" +
        "		}\n" +
        "	} )\n" +
        "	.catch( error => {\n" +
        "		console.error( error );\n" +
        "		QUnit.done();\n" +
        "	} );";

    eval( dynamicImportSource );

// Apply similar treatment for AMD modules
} else if ( config.amd && QUnit ) {
    require.config( {
        baseUrl: parentUrl
    } );
    src = "amd/jquery";

    // Include tests if specified
    if ( typeof loadTests !== "undefined" ) {
        require( [ src ], loadTests );
    } else {
        require( [ src ] );
    }

// Otherwise, load synchronously
} else {
    document.write( "<script id='jquery-js' nonce='jquery+hardcoded+nonce' src='" + parentUrl + src + "'><\x2Fscript>" );
}

赋值时候的简便写法

(() => {
    function formatDate() {
        console.log('formatDate');
    }

    function formatThousands() {
        console.log('formatThousands');
    }

    function formatTest() {
        console.log('formatTest');
    }
    ["formatDate", "formatThousands", "formatTest"].forEach(item => {
        String.prototype[item] = eval(item);
    })
})()

上面只是介绍用法可以有的思路,这类写法是不优雅的;

真实项目中,可以下面这样子写,巧妙的借助对象的特性来解决字符串的问题;

(() => {
    let Utility = {
        formatDate: function() {
            console.log('formatDate');
        },
        formatThousands: function() {
            console.log('formatThousands');
        },
        formatTest: function() {
            console.log('formatTest');
        }
    }
    Object.keys(Utility).forEach(item => {
        String.prototype[item] = Utility[item]
    })
})()

函数的拷贝

const foo = x => x + 1
console.log(eval(foo.toString())(1));

深度拷贝(引申)

下面是深度拷贝的一个引申,可以作为参考

const log = console.log;

function test() {
    'use strict';
    let obj1 = { a: 0, b: { c: 0 } };
    let obj2 = JSON.parse(JSON.stringify(obj1));
    log(JSON.stringify(obj2), '\n'); // { a: 0, b: { c: 0}}

    obj2.a = 2;
    obj2.b.c = 3;
    log(JSON.stringify(obj1)); // {"a":0,"b":{"c":3}}
    log(JSON.stringify(obj2), '\n'); //{ a: 2, b: { c: 3}}  注意obj2.b.c的值
}
test();

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了