2013-10-28 24 views
1

我通過邁克爾Fogus'電子書閱讀功能的JavaScript,和書中的例子之一是行不通的。代碼如下:錯誤功能的Javascript書例如

function existy(x) { 
    return x != null; 
}; 

function truthy(x) { 
    return (x !== false) && existy(x); 
}; 

function cat() { 
    var head = _.first(arguments); 
    if (existy(head)) 
     return head.concat.apply(head, _.rest(arguments)); 
    else 
     return []; 
}; 

function construct(head, tail) { 
    return cat([head], _.toArray(tail)); 
}; 

function rename(obj, newNames) { 
    return _.reduce(newNames, function(o, nu, old) { 
     console.log("o: " + o); 
     console.log("nu: " + nu); 
     console.log("old: " + old); 
     if (_.has(obj, old)) { 
      o[nu] = obj[old]; 
      return o; 
     } 
     else 
      return o; 
    }, 
    _.omit.apply(null, construct(old, _.keys(newNames)))); 
}; 

rename({a: 1, b: 2}, {'a': 'AAA'}); 
// => {AAA: 1, b: 2} 

除了rename(),所有的函數都能正常工作。本質上,它要採用一個對象並返回帶有用newName對象更新的屬性名稱的對象。我不完全理解它,但是reduce方法看起來並不像它有正確的參數。下面是我得到當我打電話重命名()錯誤:

ReferenceError: old is not defined 

任何幫助理解爲什麼它不工作,將不勝感激!

回答

3
function rename(obj, newNames) { 
    return _.reduce(newNames, function(o, nu, old) { 
     console.log("o: " + o); 
     console.log("nu: " + nu); 
     console.log("old: " + old); 
     if (_.has(obj, old)) { 
      o[nu] = obj[old]; 
      return o; 
     } 
     else 
      return o; 
    }, 
    _.omit.apply(null, construct(old, _.keys(newNames)))); 
} 

調用時,執行

_.reduce(newNames, function(o, nu, old) { 
    console.log("o: " + o); 
    console.log("nu: " + nu); 
    console.log("old: " + old); 
    if (_.has(obj, old)) { 
     o[nu] = obj[old]; 
     return o; 
    } 
    else 
     return o; 
}, 
_.omit.apply(null, construct(old, _.keys(newNames)))); 

這就要求

_.omit.apply(null, construct(old, _.keys(newNames))) 

old只有_.reduce的回調內部存在。如果它打算成爲第一個對象,則可以使用newNames[0]

但我不相信一本書後,函數定義把分號......


就個人而言,如果我要實現一個「功能」,它會是這個樣子:

function objectMap(obj, func) { 
    var result = {}; 

    for (var x in obj) { 
     if (obj.hasOwnProperty(x)) { 
      var r = func(x, obj[x]); 
      result[r[0]] = r[1]; 
     } 
    } 

    return result; 
} 

function rename(obj, newNames) { 
    return objectMap(obj, function(k, v) { 
     return [newNames[k] || k, v]; 
    }); 
} 
+0

+1「我不相信一本書,在函數定義之後放分號......「 –

+0

謝謝!任何建議我應該如何解決它? – EmptyArsenal

+0

@EmptyArsenal:我還不太確定它的功能。是否需要'{a:52}'和'{a:「b」}'並生成'{b:52}'? – Ryan

1

Per @ minitech,問題是'old'只存在於_.reduce回調函數中,所以當它在_.omit函數中被調用時,它已經超出了'old'的範圍。事實證明,這有一個簡單的解決辦法。如果您將「舊」更改爲「obj」(這可能是作者的意圖),該功能似乎正常工作並保留其功能性質:

function rename(obj, newNames) { 
    return _.reduce(newNames, function(o, nu, old) { 
     if (_.has(obj, old)) { 
      o[nu] = obj[old]; 
      return o; 
     } 
     else 
      return o; 
    }, 
    _.omit.apply(null, construct(obj, _.keys(newNames)))); 
}; 

rename({a: 1, b: 2}, {'a': 'AAA'}); 
// => {AAA: 1, b: 2} -> success!