ECMAScript5

张鑫旭:ECMAScript5介绍

淘宝整理的es5-safe

/*********  It provides the following methods:



Function.prototype.bind

Object.keys

Array.isArray

Array.prototype.forEach

Array.prototype.map

Array.prototype.filter

Array.prototype.every

Array.prototype.some

Array.prototype.reduce

Array.prototype.reduceRight

Array.prototype.indexOf

Array.prototype.lastIndexOf

String.prototype.trim

Date.now



**********/





(function() {



  // es5-safe

  // ----------------

  // Provides compatibility shims so that legacy JavaScript engines behave as

  // closely as possible to ES5.

  //

  // Thanks to:

  //  - http://es5.github.com/

  //  - http://kangax.github.com/es5-compat-table/

  //  - https://github.com/kriskowal/es5-shim

  //  - http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/

  //  - https://gist.github.com/1120592

  //  - https://code.google.com/p/v8/





  var OP = Object.prototype;

  var AP = Array.prototype;

  var FP = Function.prototype;

  var SP = String.prototype;

  var hasOwnProperty = OP.hasOwnProperty;

  var slice = AP.slice;





  /*---------------------------------------*

   * Function

   *---------------------------------------*/



  // ES-5 15.3.4.5

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

  FP.bind || (FP.bind = function(that) {

    var target = this;



    // If IsCallable(func) is false, throw a TypeError exception.

    if (typeof target !== 'function') {

      throw new TypeError('Bind must be called on a function');

    }



    var boundArgs = slice.call(arguments, 1);



    function bound() {

      // Called as a constructor.

      if (this instanceof bound) {

        var self = createObject(target.prototype);

        var result = target.apply(

            self,

            boundArgs.concat(slice.call(arguments))

        );

        return Object(result) === result ? result : self;

      }

      // Called as a function.

      else {

        return target.apply(

            that,

            boundArgs.concat(slice.call(arguments))

        );

      }

    }



    // NOTICE: The function.length is not writable.

    //bound.length = Math.max(target.length - boundArgs.length, 0);



    return bound;

  });





  // Helpers

  function createObject(proto) {

    var o;



    if (Object.create) {

      o = Object.create(proto);

    }

    else {

      /** @constructor */

      function F() {

      }



      F.prototype = proto;

      o = new F();

    }



    return o;

  }





  /*---------------------------------------*

   * Object

   *---------------------------------------*/

  // http://ejohn.org/blog/ecmascript-5-objects-and-properties/



  // ES5 15.2.3.14

  // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys

  // https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute

  // http://msdn.microsoft.com/en-us/library/adebfyya(v=vs.94).aspx

  Object.keys || (Object.keys = (function() {

    var hasDontEnumBug = !{toString: ''}.propertyIsEnumerable('toString');

    var DontEnums = [

      'toString',

      'toLocaleString',

      'valueOf',

      'hasOwnProperty',

      'isPrototypeOf',

      'propertyIsEnumerable',

      'constructor'

    ];

    var DontEnumsLength = DontEnums.length;



    return function(o) {

      if (o !== Object(o)) {

        throw new TypeError(o + ' is not an object');

      }



      var result = [];



      for (var name in o) {

        if (hasOwnProperty.call(o, name)) {

          result.push(name);

        }

      }



      if (hasDontEnumBug) {

        for (var i = 0; i < DontEnumsLength; i++) {

          if (hasOwnProperty.call(o, DontEnums[i])) {

            result.push(DontEnums[i]);

          }

        }

      }



      return result;

    };



  })());





  /*---------------------------------------*

   * Array

   *---------------------------------------*/

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array

  // https://github.com/kangax/fabric.js/blob/gh-pages/src/util/lang_array.js



  // ES5 15.4.3.2

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray

  Array.isArray || (Array.isArray = function(obj) {

    return OP.toString.call(obj) === '[object Array]';

  });





  // ES5 15.4.4.18

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach

  AP.forEach || (AP.forEach = function(fn, context) {

    for (var i = 0, len = this.length >>> 0; i < len; i++) {

      if (i in this) {

        fn.call(context, this[i], i, this);

      }

    }

  });





  // ES5 15.4.4.19

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map

  AP.map || (AP.map = function(fn, context) {

    var len = this.length >>> 0;

    var result = new Array(len);



    for (var i = 0; i < len; i++) {

      if (i in this) {

        result[i] = fn.call(context, this[i], i, this);

      }

    }



    return result;

  });





  // ES5 15.4.4.20

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter

  AP.filter || (AP.filter = function(fn, context) {

    var result = [], val;



    for (var i = 0, len = this.length >>> 0; i < len; i++) {

      if (i in this) {

        val = this[i]; // in case fn mutates this

        if (fn.call(context, val, i, this)) {

          result.push(val);

        }

      }

    }



    return result;

  });





  // ES5 15.4.4.16

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every

  AP.every || (AP.every = function(fn, context) {

    for (var i = 0, len = this.length >>> 0; i < len; i++) {

      if (i in this && !fn.call(context, this[i], i, this)) {

        return false;

      }

    }

    return true;

  });





  // ES5 15.4.4.17

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some

  AP.some || (AP.some = function(fn, context) {

    for (var i = 0, len = this.length >>> 0; i < len; i++) {

      if (i in this && fn.call(context, this[i], i, this)) {

        return true;

      }

    }

    return false;

  });





  // ES5 15.4.4.21

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce

  AP.reduce || (AP.reduce = function(fn /*, initial*/) {

    if (typeof fn !== 'function') {

      throw new TypeError(fn + ' is not an function');

    }



    var len = this.length >>> 0, i = 0, result;



    if (arguments.length > 1) {

      result = arguments[1];

    }

    else {

      do {

        if (i in this) {

          result = this[i++];

          break;

        }

        // if array contains no values, no initial value to return

        if (++i >= len) {

          throw new TypeError('reduce of empty array with on initial value');

        }

      }

      while (true);

    }



    for (; i < len; i++) {

      if (i in this) {

        result = fn.call(null, result, this[i], i, this);

      }

    }



    return result;

  });





  // ES5 15.4.4.22

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight

  AP.reduceRight || (AP.reduceRight = function(fn /*, initial*/) {

    if (typeof fn !== 'function') {

      throw new TypeError(fn + ' is not an function');

    }



    var len = this.length >>> 0, i = len - 1, result;



    if (arguments.length > 1) {

      result = arguments[1];

    }

    else {

      do {

        if (i in this) {

          result = this[i--];

          break;

        }

        // if array contains no values, no initial value to return

        if (--i < 0)

          throw new TypeError('reduce of empty array with on initial value');

      }

      while (true);

    }



    for (; i >= 0; i--) {

      if (i in this) {

        result = fn.call(null, result, this[i], i, this);

      }

    }



    return result;

  });





  // ES5 15.4.4.14

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf

  AP.indexOf || (AP.indexOf = function(value, from) {

    var len = this.length >>> 0;



    from = Number(from) || 0;

    from = Math[from < 0 ? 'ceil' : 'floor'](from);

    if (from < 0) {

      from = Math.max(from + len, 0);

    }



    for (; from < len; from++) {

      if (from in this && this[from] === value) {

        return from;

      }

    }



    return -1;

  });





  // ES5 15.4.4.15

  // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf

  AP.lastIndexOf || (AP.lastIndexOf = function(value, from) {

    var len = this.length >>> 0;



    from = Number(from) || len - 1;

    from = Math[from < 0 ? 'ceil' : 'floor'](from);

    if (from < 0) {

      from += len;

    }

    from = Math.min(from, len - 1);



    for (; from >= 0; from--) {

      if (from in this && this[from] === value) {

        return from;

      }

    }



    return -1;

  });





  /*---------------------------------------*

   * String

   *---------------------------------------*/



  // ES5 15.5.4.20

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/trim

  // http://blog.stevenlevithan.com/archives/faster-trim-javascript

  // http://jsperf.com/mega-trim-test

  SP.trim || (SP.trim = (function() {



    // http://perfectionkills.com/whitespace-deviations/

    var whiteSpaces = [



      '\\s',

      //'0009', // 'HORIZONTAL TAB'

      //'000A', // 'LINE FEED OR NEW LINE'

      //'000B', // 'VERTICAL TAB'

      //'000C', // 'FORM FEED'

      //'000D', // 'CARRIAGE RETURN'

      //'0020', // 'SPACE'



      '00A0', // 'NO-BREAK SPACE'

      '1680', // 'OGHAM SPACE MARK'

      '180E', // 'MONGOLIAN VOWEL SEPARATOR'



      '2000-\\u200A',

      //'2000', // 'EN QUAD'

      //'2001', // 'EM QUAD'

      //'2002', // 'EN SPACE'

      //'2003', // 'EM SPACE'

      //'2004', // 'THREE-PER-EM SPACE'

      //'2005', // 'FOUR-PER-EM SPACE'

      //'2006', // 'SIX-PER-EM SPACE'

      //'2007', // 'FIGURE SPACE'

      //'2008', // 'PUNCTUATION SPACE'

      //'2009', // 'THIN SPACE'

      //'200A', // 'HAIR SPACE'



      '200B', // 'ZERO WIDTH SPACE (category Cf)

      '2028', // 'LINE SEPARATOR'

      '2029', // 'PARAGRAPH SEPARATOR'

      '202F', // 'NARROW NO-BREAK SPACE'

      '205F', // 'MEDIUM MATHEMATICAL SPACE'

      '3000' //  'IDEOGRAPHIC SPACE'



    ].join('\\u');



    var trimLeftReg = new RegExp('^[' + whiteSpaces + ']+');

    var trimRightReg = new RegExp('[' + whiteSpaces + ']+$');



    return function() {

      return String(this).replace(trimLeftReg, '').replace(trimRightReg, '');

    }



  })());





  /*---------------------------------------*

   * Date

   *---------------------------------------*/



  // ES5 15.9.4.4

  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now

  Date.now || (Date.now = function() {

    return +new Date;

  });



})();
View Code

 

你可能感兴趣的:(ECMAScript)