Javascript面试题:让[1,2,3].sum()运行

Javascript 面试问题: 在不使用和,的[1,2,3].sum()情况下运行精确的代码。PrototypeObject.definePropertyObject.defineProperties

既然这是一个面试问题,我想有办法让它发挥作用吗?

任何帮助/指示表示赞赏。

谢谢


叮当猫咪
浏览 85回答 3
3回答

汪汪一只猫

前言:像这样的问题并不能真正表明某人是一个“好的”程序员,它只是意味着他们熟悉语言中的技巧,而这些技巧不会带来更易于维护的代码。对于经常使用此类技巧的公司或团队,我会保持警惕。(就我个人而言:当我还是 Microsoft 的 SE 时,我曾研究过 Chakra JavaScript 引擎,我喜欢认为我非常了解 JavaScript/ECMAScript,但我仍然需要思考很长一段时间如何在没有使用prototype或defineProperty- 所以这就是为什么我认为如果他们期望得到直接答案,这不是一个好的技术面试问题- 但如果这是一个旨在提示你向面试官提问的面试问题,那么那就不同了)。选项 1:全局错误处理程序:这是一个可怕的方法:window.addEventListener( 'error', function( e ) {        if( e.error instanceof ErrorEvent || e.error instanceof TypeError ) {                const msg = e.error.message;        const suffixIdx = msg.indexOf( ".sum is not a function" );        if( suffixIdx > -1 ) {            const arrayStr = msg.substring( 0, suffixIdx );                        const arr = eval( arrayStr ); // <-- lolno            const total = arr.reduce( ( sum, e ) => sum + e, 0 );            console.log( total ); // 6        }    }    } );[1,2,3].sum()@NenadVracar 发布了一个简化版本eval,尽管它使用本地 ,但它避免了try:try {    [1,2,3].sum()} catch (err) {    const result = err.message    .match(/\[(.*?)\]/)[1]    .split(',')    .reduce((r, e) => r + +e, 0)      console.log(result)}选项 2:重写Array构造函数如果您使用的是较旧的 JavaScript 引擎(2010 年之前创建的或 ECMAScript 5),则重写构造函数的脚本Array将在脚本遇到数组文字时使用该构造函数,并且.sum可以通过这种方式添加该方法:Array = function() { // <-- THIS WILL NOT WORK IN BROWSERS MADE AFTER 2010!    this.sum = function() {        var total = 0;        for( var i = 0; i < this.length; i++ ) {            total += this[i];        }        return total;    };};let total = [1,2,3].sum();console.log( total );选项 3:偷偷摸摸地处理财产prototype:正如其他人在评论中提到的,如果您将这些成员作为字符串访问,您仍然可以改变prototype成员或使用:Object.definePropertyArray[ 'proto' + 'type' ].sum = function() {    var total = 0;    for( var i = 0; i < this.length; i++ ) {        total += this[i];    }    return total;};let total = [1,2,3].sum();console.log( total );

浮云间

我们能在多大程度上绕过这里的界限?假设我们希望下面的行起作用,[1, 2, 3].sum();那么我们可以很容易地让它做一些事情。请注意,由于自动分号插入规则,您所拥有的不一定是数组。它可能是带有逗号运算符的数组访问。({3: {sum: () => console.log(6)}}) //<-- object[1,2,3].sum(); //<-- array access或者为了更清楚,这里是等效的代码:const obj = {  3: {    sum: () => console.log(6)  }};obj[3].sum(); //<-- array access因为,我没有看到应sum该做什么的定义,所以上面涵盖了列出的所有要求 - 没有原型恶作剧,没有额外的属性。好吧,从技术上讲,sum没有总结任何东西,但这里有一个解决方法:像这样定义它sum: (a, b) => a + b现在,从技术上讲,它是一个将两个数字相加的函数。毕竟,不需要对1, 2, 3调用之前出现的序列求和。sum

繁花不似锦

或者为了更清楚,这里是等效的代码:const obj = {  3: {    sum: () => console.log(6)  }};obj[3].sum(); //<-- array access将其作为披萨/表情符号示例向您展示的目的是您可以解决此类测试。当然,前面的代码可以简化为另一个更严重的代码片段,这也满足了使用 提出的问题的目的__proto__。[3]['__proto__']['sum'] = () => { console.log('this runs!, answer is 6'); };[1,2,3].sum();/** * Here am using `__proto__` instead  * of `Prototype`, they are both almost the same  * but `__proto__` works for instances only. * **/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript