compat.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * compat.js — 老浏览器标准库补丁
  3. *
  4. * 本文件补的是 ES2015+ 的“语言标准库方法”,IE11 及同期浏览器没有:
  5. * String: padStart(ES2017) / startsWith / endsWith / includes(ES2015)
  6. * Array: includes(ES2016)
  7. * Object: assign(ES2015)
  8. *
  9. * 注意:
  10. * 1. 文件用 ES5 语法书写(IE11 不认识箭头函数、let/const),
  11. * 但这指的是写法,不是补 ES5 的能力 —— 补的均是 ES2015+ 的方法。
  12. * 2. Promise(ES2015) / fetch / EventSource 属于运行时与平台 API,
  13. * 不在本文件,由同目录 promise.min.js、fetch.min.js、
  14. * eventsource.min.js 提供;三者在加载时检测原生能力,存在则不覆盖。
  15. * 3. 本文件不依赖上述三者,但必须在业务 JS 之前加载。
  16. * 4. downloadBlobFile() 保留在 util.js,不放在这里。
  17. */
  18. (function () {
  19. "use strict";
  20. /* =========================================================
  21. * String
  22. * ========================================================= */
  23. if (!String.prototype.padStart) {
  24. String.prototype.padStart = function (targetLength, padString) {
  25. var str = String(this);
  26. var len = Number(targetLength) || 0;
  27. var pad = padString === undefined ? " " : String(padString);
  28. var need = len - str.length;
  29. var result = "";
  30. if (need <= 0) return str;
  31. if (pad === "") return str;
  32. while (result.length < need) {
  33. result += pad;
  34. }
  35. return result.slice(0, need) + str;
  36. };
  37. }
  38. if (!String.prototype.startsWith) {
  39. String.prototype.startsWith = function (search, position) {
  40. var str = String(this);
  41. var pos = Number(position) || 0;
  42. search = String(search);
  43. if (pos < 0) pos = 0;
  44. return str.substr(pos, search.length) === search;
  45. };
  46. }
  47. if (!String.prototype.endsWith) {
  48. String.prototype.endsWith = function (search, length) {
  49. var str = String(this);
  50. search = String(search);
  51. if (length === undefined || length > str.length) {
  52. length = str.length;
  53. }
  54. length = Number(length);
  55. if (isNaN(length) || length < 0) length = 0;
  56. return str.substring(length - search.length, length) === search;
  57. };
  58. }
  59. if (!String.prototype.includes) {
  60. String.prototype.includes = function (search, start) {
  61. if (search instanceof RegExp) {
  62. throw new TypeError("不支持将 RegExp 作为 includes 参数");
  63. }
  64. return String(this).indexOf(String(search), Number(start) || 0) !== -1;
  65. };
  66. }
  67. /* =========================================================
  68. * Array
  69. * ========================================================= */
  70. if (!Array.prototype.includes) {
  71. Array.prototype.includes = function (search, fromIndex) {
  72. var arr = Object(this);
  73. var len = arr.length >>> 0;
  74. var i = Number(fromIndex) || 0;
  75. if (!len) return false;
  76. // 按 ToInteger 向零截断,否则 fromIndex 为负小数时会从错误下标起扫
  77. i = i < 0 ? Math.ceil(i) : Math.floor(i);
  78. if (i < 0) {
  79. i = Math.max(len + i, 0);
  80. }
  81. for (; i < len; i++) {
  82. if (arr[i] === search ||
  83. (arr[i] !== arr[i] && search !== search)) {
  84. return true;
  85. }
  86. }
  87. return false;
  88. };
  89. }
  90. /* =========================================================
  91. * Object
  92. * ========================================================= */
  93. if (!Object.assign) {
  94. Object.assign = function (target) {
  95. if (target == null) {
  96. throw new TypeError("Object.assign 的目标不能为 null 或 undefined");
  97. }
  98. var to = Object(target);
  99. var i;
  100. var source;
  101. var key;
  102. for (i = 1; i < arguments.length; i++) {
  103. source = arguments[i];
  104. if (source == null) continue;
  105. source = Object(source);
  106. for (key in source) {
  107. if (Object.prototype.hasOwnProperty.call(source, key)) {
  108. to[key] = source[key];
  109. }
  110. }
  111. }
  112. return to;
  113. };
  114. }
  115. })();