2013-10-28 22 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!