Resolve the issue there were two types of objects was not iterable

I saw the issues [#148](https://github.com/jashkenas/underscore/issues/148), [#659](https://github.com/jashkenas/underscore/issues/659), [#937](https://github.com/jashkenas/underscore/issues/937), [#1590](https://github.com/jashkenas/underscore/issues/1590),
and I found if use 'obj.length === +obj.length' or 'obj.length !== +obj.length' to judge whether the object is an array or not, there will be two things not iterable.

###### 1. Object which contains 'length' property with 'Number' type value are not iterable:

    var obj = { length:3,width:3,height:3 };
    _.reduce(obj, function(memo, value){ return memo + value; }); // NaN

###### 2. Objects with [object Function] type are not iterable:

    // The value of [object Function]'s 'length' property is arguments' length, and it was unable to be modify.
    var func1 = function(){}, func2 = function(a){}, func3 = function(a,b){};
    func1.one= func2.one = func3.one = 1, func1.two = func2.two  = func3.two = 2;
    _.reduce(func1, function(memo, value){ return memo + value; });  // TypeError: Reduce of empty array with no initial value
    _.reduce(func2, function(memo, value){ return memo + value; });  // return: undefined
    _.reduce(func3, function(memo, value){ return memo + value; });  // return: NaN
    _.each(func2, function(value){ console.log(value); });  // log on console: undefined
    _.each(func3, function(value){ console.log(value); });  // log on console: undefined undefined

-------------------------------------------

##### Only in the var with String or Array type, 'length' property are 'useful' in only these two cases, so we can use fucntion '_.isObject'.

###### 1. To replace codes like 'obj.length !== +obj.length' in underscore.js with '_.isObject(obj)', 
( variable values like {}, function(){}, /reg/, new RegExp, new String, new Date... will all pass, 
and var like new String('123') or new Array(1,2) can also be iterated correctly as an object)

###### 2. To replace codes like 'obj.length === +obj.length' with '!_.isObject(obj)', then reverse some judgement from '!_.isObject(obj)' to '_.isObject(obj)'
( only literal value like 'abc' or [1,2,3] will pass ),And I 


##### After fixing:

    var obj = { length:3, width:3, height:3 };
    _.reduce(obj, function(memo, value){ return memo + value; });  // return: 9 

    var func = function(a){}; func.one = 1, func.two = 2;
    _.reduce(func, function(memo, value){ return memo + value; }, 0);  // return: 3 
    _.each(func, function(value){ console.log(value); });  // log on console: 1 2

    var date = new Date();
    date.name = 'my date', date.length = 1, date.begin = date.getTime();
    _.reduce(date, function( memo, value, key){ return memo + key + '=' + value + '; '; }, 'date info: '); 
    // return: "date info: name=my date; length=1; begin=1414486668471; "

    _.reduce(new String('123'), function(memo, value){ return value + memo; });      // return: "321"
    _.reduce('123', function(memo, value){ return value + memo; });                  // return: "321"
    _.each(new String('123'), function(value, index){ console.log(value, index); }); // log on console: "1" 0 / "2" 1 / "3" 2
    _.each('123', function(value, index){ console.log(value, index); });             // log on console: "1" 0 / "2" 1 / "3" 2
    _.each(new Array(1,2,3), function(value, index){ console.log(value, index); });  // log on console: 1 "0" / 2 "1" / 3 "2"
    _.each([1,2,3], function(value, index){ console.log(value, index); });           // log on console: 1 "0" / 2 "1" / 3 "2"

-------

#### test case for function 'reduce':

    test('reduce', function() {
      var sum = _.reduce('123', function(string, char){ return +string + +char; }, 0);
      equal(sum, '6', 'can sum up a string with all number type chars'); 

      var rec = _.reduce('123', function(string, char){ return char + string; });
      equal(rec, '321', 'can recombine a string'); 

      rec = _.reduce('12ab', function(sum, num){ return sum + ',' + num; });
      equal(rec, '1,2,a,b', 'can recombine a string'); 

      sum = _.reduce({length:1,width:2,height:3}, function(sum, num){ return sum + num; }, 0);
      equal(sum, 6, 'can sum up an object's all own property value, include its 'lenght' property);

      var func = function(a,b){}; // func.length === 2
      func.one = 1,func.two = 2,func.three = 3;
      sum = _.reduce(func, function(sum, num){ return sum + num; }, 0);
      equal(sum, 6, 'can sum up an function's all own property value except its 'lenght' property); // not count the value of 'length' property.  

      // origin cases all below also pass ---------------------

      var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0);
      equal(sum, 6, 'can sum up an array');

      var context = {multiplier : 3};
      sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context);
      equal(sum, 18, 'can reduce with a context object');

      sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0);
      equal(sum, 6, 'aliased as "inject"');

      sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0);
      equal(sum, 6, 'OO-style reduce');

      sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; });
      equal(sum, 6, 'default initial value');

      var prod = _.reduce([1, 2, 3, 4], function(prod, num){ return prod * num; });
      equal(prod, 24, 'can reduce via multiplication');

      ok(_.reduce(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
      equal(_.reduce([], _.noop, undefined), undefined, 'undefined can be passed as a special case');
      equal(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item');

      throws(function() { _.reduce([], _.noop); }, TypeError, 'throws an error for empty arrays with no initial value');
      throws(function() {_.reduce(null, _.noop);}, TypeError, 'handles a null (without initial value) properly');
    });