3 回答

TA貢獻(xiàn)1898條經(jīng)驗(yàn) 獲得超8個(gè)贊
前言:像這樣的問(wèn)題并不能真正表明某人是一個(gè)“好的”程序員,它只是意味著他們熟悉語(yǔ)言中的技巧,而這些技巧不會(huì)帶來(lái)更易于維護(hù)的代碼。對(duì)于經(jīng)常使用此類技巧的公司或團(tuán)隊(duì),我會(huì)保持警惕。
(就我個(gè)人而言:當(dāng)我還是 Microsoft 的 SE 時(shí),我曾研究過(guò) Chakra JavaScript 引擎,我喜歡認(rèn)為我非常了解 JavaScript/ECMAScript,但我仍然需要思考很長(zhǎng)一段時(shí)間如何在沒(méi)有使用prototype
或defineProperty
- 所以這就是為什么我認(rèn)為如果他們期望得到直接答案,這不是一個(gè)好的技術(shù)面試問(wèn)題- 但如果這是一個(gè)旨在提示你向面試官提問(wèn)的面試問(wèn)題,那么那就不同了)。
選項(xiàng) 1:全局錯(cuò)誤處理程序:
這是一個(gè)可怕的方法:
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 發(fā)布了一個(gè)簡(jiǎn)化版本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)
}
選項(xiàng) 2:重寫Array
構(gòu)造函數(shù)
如果您使用的是較舊的 JavaScript 引擎(2010 年之前創(chuàng)建的或 ECMAScript 5),則重寫構(gòu)造函數(shù)的腳本Array
將在腳本遇到數(shù)組文字時(shí)使用該構(gòu)造函數(shù),并且.sum
可以通過(guò)這種方式添加該方法:
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 );
選項(xiàng) 3:偷偷摸摸地處理財(cái)產(chǎn)prototype
:
正如其他人在評(píng)論中提到的,如果您將這些成員作為字符串訪問(wèn),您仍然可以改變prototype
成員或使用:Object.defineProperty
Array[ '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 );

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超4個(gè)贊
我們能在多大程度上繞過(guò)這里的界限?
假設(shè)我們希望下面的行起作用,[1, 2, 3].sum();
那么我們可以很容易地讓它做一些事情。請(qǐng)注意,由于自動(dòng)分號(hào)插入規(guī)則,您所擁有的不一定是數(shù)組。它可能是帶有逗號(hào)運(yùn)算符的數(shù)組訪問(wèn)。
({3: {sum: () => console.log(6)}}) //<-- object
[1,2,3].sum(); //<-- array access
或者為了更清楚,這里是等效的代碼:
const obj = {
? 3: {
? ? sum: () => console.log(6)
? }
};
obj[3].sum(); //<-- array access
因?yàn)?,我沒(méi)有看到應(yīng)sum
該做什么的定義,所以上面涵蓋了列出的所有要求 - 沒(méi)有原型惡作劇,沒(méi)有額外的屬性。
好吧,從技術(shù)上講,sum
沒(méi)有總結(jié)任何東西,但這里有一個(gè)解決方法:像這樣定義它
sum:?(a,?b)?=>?a?+?b
現(xiàn)在,從技術(shù)上講,它是一個(gè)將兩個(gè)數(shù)字相加的函數(shù)。畢竟,不需要對(duì)1, 2, 3
調(diào)用之前出現(xiàn)的序列求和。sum

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超4個(gè)贊
或者為了更清楚,這里是等效的代碼:
const obj = {
? 3: {
? ? sum: () => console.log(6)
? }
};
obj[3].sum(); //<-- array access
將其作為披薩/表情符號(hào)示例向您展示的目的是您可以解決此類測(cè)試。
當(dāng)然,前面的代碼可以簡(jiǎn)化為另一個(gè)更嚴(yán)重的代碼片段,這也滿足了使用 提出的問(wèn)題的目的__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.
?*
?**/
添加回答
舉報(bào)