SOURCE

function print(x) {
  document.write(x);
}

//-- 1.1 Javacript 案例
(function(){
  // Javascript “天然”支持函数式编程
  [1,2,3].forEach(print);
  print('<br>');
})();

//-------------------------------
(function(){
  // 函数的返回值是另一个函数
  function splat(fn) {
    return function(array) {
      return fn.apply(null, array);
    };
  }
  
  var addArrayElements = splat(function(x, y){ return x + y; });
  print( addArrayElements([1, 2]) );
  print('<br>');
  
  function unsplat(fn) {
    return function() {
      return fn.call(null, _.toArray(arguments));
    };
  }
  
  var joinElements = unsplat(function(array) { return array.join(' ') });
  print( joinElements(1,2,3,4,5) );
  print('<br>'); 
  
})();


//-- 1.2 开始函数式编程
(function(){
  // 函数式编程通过使用函数来将值转换成抽象单元,接着用于构建软件系统
  // 它的主要目标是问题分解。
  // 与面向对象方法将问题分解成多组“名词”或对象不同,
  // 函数式方法将相同的问题分解成多组“动词”或函数。
  
  // 1.2.2 以函数为抽象单元
  function pareseAge(age) {
    if (!_.isString(age)) throw new Error('Expecting a string.');
    
    var a;
    print( 'Attempting to parse an age.' );
    
    a = parseInt(age, 10);
    if (_.isNaN(a)) {
      conole.log(['Could not parse age: ', age].join(' '));
      a = 0;
    }
    
    return a;
  }

  print( pareseAge('42') );
  print( pareseAge(42) );
  print( pareseAge('hehe') );
  
}); //();

//-------------------------------
(function(){
  // 将错误、信息和警告的概念抽象成不同的函数
  function fail(thing) {
    throw new Error(thing);
  }
  
  function warn(thing) {
    console.log(['WARNING:', thing].join(' '));
  }
  
  function note(thing) {
    console.log(['NOTE:', thing].join(' '));
  }
  
  // 改进 pareseAge
  function pareseAge(age) {
    if (!_.isString(age)) fail('Expecting a string.');
    
    var a;
    note( 'Attempting to parse an age.' );
    
    a = parseInt(age, 10);
    if (_.isNaN(a)) {
      warn(['Could not parse age: ', age].join(' '));
      a = 0;
    }
    
    return a;
  }
  
  print( pareseAge('hehe') );



//-- 1.2.3 封装和隐藏
// JS 使用闭包的方式来隐藏数据

// 1.2.4 以函数为行为单位

  var letters = ['a', 'b', 'c', 'd'];
  console.log( letters[2] );
  
  // 抽象数组索引行为
  function naiveNth(a, index) {
    return a[index];
  }
  
  console.log( naiveNth(letters, 3) );
  console.log( naiveNth({}, 3) );
  
  // 鲁棒性 改进
  // 判断是否为 索引的数据类型
  function isIndexed(data) {
    return _.isArray(data) || _.isString(data);
  }
  
  function nth(a, index) {
    if (!_.isNumber(index)) fail('Expected a number as the index.');
    if (!isIndexed(a)) fail('Not supported on non-indexed type.');
    if ((index < 0) || (index > a.length - 1)) fail('Index value is out of bounds.');
    
    return a[index];
  }
  
  console.log('-----nth()-----');
  console.log(nth(letters, 1));
  
})();













console 命令行工具 X clear

                    
>
console