前端

How Smart Tools Are Shaping the Future of Creative Work

Eric Chuang
2020-11-10

問題

給定 14 個函式,從 zero() 到 nine()、plus()、minus()、times() 及 dividedBy(),寫出可以進行簡單四則運算的函式。如:zero( plus( three() ) ); 會回傳 3。

我的解法

function zero(r) {
  return r === undefined ? 0 : Function( 'return Math.floor(' + 0 + r + ')' )();
}
function one(r) {
  return r === undefined ? 1 : Function( 'return Math.floor(' + 1 + r + ')' )();
}
function two(r) {
  return r === undefined ? 2 : Function( 'return Math.floor(' + 2 + r + ')' )();
}
function three(r) {
  return r === undefined ? 3 : Function( 'return Math.floor(' + 3 + r + ')' )();
}
function four(r) {
  return r === undefined ? 4 : Function( 'return Math.floor(' + 4 + r + ')' )();
}
function five(r) {
  return r === undefined ? 5 : Function( 'return Math.floor(' + 5 + r + ')' )();
}
function six(r) {
  return r === undefined ? 6 : Function( 'return Math.floor(' + 6 + r + ')' )();
}
function seven(r) {
  return r === undefined ? 7 : Function( 'return Math.floor(' + 7 + r + ')' )();
}
function eight(r) {
  return r === undefined ? 8 : Function( 'return Math.floor(' + 8 + r + ')' )();
}
function nine(r) {
  return r === undefined ? 9 : Function( 'return Math.floor(' + 9 + r + ')' )();
}

function plus(p) {
  return '+' + p;
}
function minus(p) {
  return '-' + p;
}
function times(p) {
  return '*' + p;
}
function dividedBy(p) {
  return '/' + p;
}

票選最佳解法

function zero(func)   { return func ? func(0) : 0; };
function one(func)    { return func ? func(1) : 1; };
function two(func)    { return func ? func(2) : 2; };
function three(func)  { return func ? func(3) : 3; };
function four(func)   { return func ? func(4) : 4; };
function five(func)   { return func ? func(5) : 5; };
function six(func)    { return func ? func(6) : 6; };
function seven(func)  { return func ? func(7) : 7; };
function eight(func)  { return func ? func(8) : 8; };
function nine(func)   { return func ? func(9) : 9; };

function plus( b )      { return function( a ) { return a + b; }; };
function minus( b )     { return function( a ) { return a - b; }; };
function times( b )     { return function( a ) { return a * b; }; };
function dividedBy( b ) { return function( a ) { return a / b; }; };

改善點

原本的做法是透過類似 eval() 的方式來解決,用 plus()、minus()、times() 與 dividedBy() 組成字串後,再用 Functions( 'return ...' )(); 的方式來執行。

但是其實可以透過遞迴函式的方式解決。

遞迴函式一直是我的弱點。

以 one( plus( two() ) ) 為例,我們可以將整段運算分成兩個階段來看:one( plus() ) 與 plus( two() )。

在 one( plus() ) 這段中,會回傳 plus( 1 ),接著變成 plus() 中的 function ( a ) 的 a,而原本的 plus( two() ) 則會將 2 帶入 b 中。

用 console.log() 來捕捉每個步驟的話,會得出下列的結果:

function zero(func)   {
  console.log( 'func is: ' + func );
  return func ? func(0) : 0;
};

function one(func)    {
  console.log( 'func is: ' + func );
  return func ? func(1) : 1;
};

function two(func)    {
  console.log( 'func is: ' + func );
  return func ? func(2) : 2;
};

function three(func)  {
  console.log( 'func is: ' + func );
  return func ? func(3) : 3;
};

function four(func)   {
  console.log( 'func is: ' + func );
  return func ? func(4) : 4;
};

function five(func)   {
  console.log( 'func is: ' + func );
  return func ? func(5) : 5;
};

function six(func)    {
  console.log( 'func is: ' + func );
  return func ? func(6) : 6;
};

function seven(func)  {
  console.log( 'func is: ' + func );
  return func ? func(7) : 7;
};

function eight(func)  {
  console.log( 'func is: ' + func );
  return func ? func(8) : 8;
};

function nine(func)   {
  console.log( 'func is: ' + func );
  return func ? func(9) : 9;
};


function plus( b ) {
  return function( a ) {
    console.log( 'a is: ' + a + ' and b is: ' + b );
    return a + b; };
};

function minus( b ) {
  return function( a ) {
    console.log( 'a is: ' + a + ' and b is: ' + b );
    return a - b; };
};

function times( b ) {
  return function( a ) {
    console.log( 'a is: ' + a + ' and b is: ' + b );
    return a * b; };
};

function dividedBy( b ) {
  return function( a ) {
    console.log( 'a is: ' + a + ' and b is: ' + b );
    return a / b; };
};
Input: one(plus())
Console: func is: function( a ) { console.log( 'a is: ' + a + ' and b is: ' + b );return a + b; }
Console: a is: 1 and b is: undefined
Output: NaN // 這是 1 + undefined 的結果

Input: plus( one() )
Console: func is: undefined // one() 會回傳 1 給 plus(),但不會印出來
Output: ƒ ( a ) { console.log( 'a is: ' + a + ' and b is: ' + b );return a + b; }

Input: one()
Console: func is: undefined // one() 回傳 1 給主控台
Output: 1

Input: plus() // plus() 回傳一個函式給主控台
Output: ƒ ( a ) { console.log( 'a is: ' + a + ' and b is: ' + b );return a + b; }

Input: one(plus(two()))
Console: func is: undefined // two() 回傳 2 給 plus(),不會印出來
Console: func is: function( a ) { console.log( 'a is: ' + a + ' and b is: ' + b );return a + b; }
// one(plus()) 回傳 1 到 function(a) 當中
Console: a is: 1 and b is: 2
Output: 3

參考資料

Sign up for our newsletter

Subscribe to our newsletter to receive the latest updates, expert insights, and practical tips directly in your inbox. Stay informed with content designed to help you grow.

+480.000 happy customers

Gain more with expert solutions

Unlock the full potential of your business with our expert solutions. Our team provides tailored strategies, professional guidance, and actionable insights to help you achieve better results.

  • Eric Chuang
  • •
  • 2025-01-23
如何同時使用 Webinoly 與 Cloudflare 保護網站安全

在社群夥伴勇哥的文章〈Webinoly 最新版快速安裝〉中,提到使用 Webinoly 來建立 WordPre […]

主機