diff --git a/History.md b/History.md index af6b2a1..2946f9d 100644 --- a/History.md +++ b/History.md @@ -1,17 +1,22 @@ +2.0.0 / 2020-09-18 +================== + * 重构, 分cjs版和esm版。 + + 1.1.1 / 2018-06-29 ================== - * add Number.parse + * 增加 Number.parse 1.0.1 / 2018-05-25 ================== - * delete global extends - * add Promise.defer extend + * 删除 global 拓展 + * 增加 Promise.defer 0.0.3 / 2017-03-17 ================== - * Optimise String extend function. + * 优化 String 拓展. 0.0.1 / 2017-02-28 ================== diff --git a/Readme.md b/Readme.md index 72aba59..437ecb6 100644 --- a/Readme.md +++ b/Readme.md @@ -1,19 +1,17 @@ ![module info](https://nodei.co/npm/es.shim.png?downloads=true&downloadRank=true&stars=true) # es.shim -> `es.shim` is an extend module for letting you can use some future api in current Node.js version. -> Also some useful api for you. +> `es.shim` 提供了部分新API, 以及一些常用的扩展方法。具体如下: + Obejct * empty() -+ Obejct.prototype - * merge() - + Array.prototype - * includes() + * flat() + * flatMap() + * item() @@ -33,135 +31,14 @@ * tohtml() * xss() * escape() - * padStart() - * padEnd() + * item() + Number * parse() + * fromString() - ++ Promise + * defer() -## Usage - -### 1. Object.prototype.merge() -```javascript -let obj1 = {a: 123, b: 456} -let obj2 = {a: 22, c: 44} -let obj3 = {c: 11, e: 55} - -o1.merge(o2) -// now obj1 is {a: 22, b: 456, c: 44} -// nothing to obj2 - -o1.merge(o2, o3) -// obj1 will be {a: 22, b: 456, c: 11, e: 55} -// nothing to obj2 & obj3 - -``` - -### 2. Object.empty() -```javascript -Object.empty({}) // true -Object.empty({a: 213}) // false -Object.empty([]) // true -Object.empty([null]) // false -Object.empty([undefined]) // false - -``` - - -### 3. Array.prototype.includes() -```javascript -let arr = [1, '3', 54, 32, 'foo'] - -arr.includes(1) // true -arr.includes(3) // false -arr.includes('bar') // false -arr.includes('54') // false - -``` - - -### 4. Date.isDate() -```javascript - -Date.isDate(new Date()) // true -Date.isDate({}) // false -Date.isDate(['bar']) // false -Date.isDate('foo') // false - -``` - - -### 5. Date.prototype.format(format) -> `format` can be these below: -> - Y (with century) eg. 1970,2017 -> - y (without century) eg. 70, 117 -> - m month, 01-12 -> - n month, 1-12 -> - d date, 01-31 -> - j date, 1-31 -> - H hours 00-23 -> - h hours 00-12 -> - G hours 0-23 -> - g hours 0-12 -> - i minutes, 00-59 -> - s seconds, 00-59 -> - W how many weeks from 01-01 this year -> - w how many weeks from 01 this month -> - D week name, like Mon, Tue, Wed, Thu, Fri, Sat, Sun - -```javascript - -new Date().format() // default 2017-02-08 12:11:23 -new Date().format('Y-m-d') // 2017-02-08 -new Date().format('Y/n/j') // 2017/2/8 -new Date().format('Y年n月j日 第W周') // 2017年2月10日 第6周 -new Date('Wed Feb 10 2016 23:34:04 GMT+0800 (CST)').format() // 2016-02-10 23:34:04 -new Date('2016-08-10T13:14:44.000Z').format() //2016-08-10 21:14:44 -new Date(1470834884000).format('') //2016-08-10 21:14:44 - -``` - - -### 6. String.prototype.splice(start, len[, fill]) -- start `` -- len `` -- fill `` - -```javascript -let str = 'Hello baby'; - -str.splice(0, 5) // return ' baby' -console.log(str) // nothing tostr, so it return 'Hello baby' - -str.splice(0, 5, 'Love') //return 'Love baby' - -str.splice(6, 0, 'world, ')// return 'Hello world, baby' - -str = str.splice(6) //return 'Holle ' - -``` - - -### 7. String.prototype.htmlspecialchars([sign]) -> Just like php's function - `htmlspecialchars` -- sign `` (ENT_QUOTES/ENT_NOQUOTES) - -```javascript -let str = `` - -str.htmlspecialchars() // <script>alert('hello world')</script> -str.htmlspecialchars('ENT_QUOTES') // <script>alert('hello world')</script> - -``` - - -### 8. String.prototype.tohtml() -```javascript -let str = `<script>alert('hello world')</script>` -str.tohtml() // - -``` diff --git a/index.js b/index.js index 0d90b89..798c619 100644 --- a/index.js +++ b/index.js @@ -5,11 +5,9 @@ * */ -'use strict' - -require('./lib/object') -require('./lib/array') -require('./lib/string') -require('./lib/number') -require('./lib/date') -require('./lib/promise') +require('./lib/cjs/object') +require('./lib/cjs/array') +require('./lib/cjs/string') +require('./lib/cjs/number') +require('./lib/cjs/date') +require('./lib/cjs/promise') diff --git a/index.mjs b/index.mjs new file mode 100644 index 0000000..17bbbc1 --- /dev/null +++ b/index.mjs @@ -0,0 +1,13 @@ +/** + * + * @authors yutent (yutent@doui.cc) + * @date 2017-02-27 18:01:54 + * + */ + +import './lib/esm/object' +import './lib/esm/array' +import './lib/esm/string' +import './lib/esm/number' +import './lib/esm/date' +import './lib/esm/promise' diff --git a/lib/array.js b/lib/array.js deleted file mode 100644 index b118082..0000000 --- a/lib/array.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * - * @authors yutent (yutent@doui.cc) - * @date 2017-02-27 21:56:03 - * - */ - -'use strict' - -// 判断数组是否包含指定元素 -if (!Array.prototype.includes) { - Object.defineProperty(Array.prototype, 'includes', { - value: function(val) { - for (let it of this) { - if (it === val) { - return true - } - } - return false - }, - enumerable: false, - writable: true - }) -} diff --git a/lib/cjs/array.js b/lib/cjs/array.js new file mode 100644 index 0000000..638f69a --- /dev/null +++ b/lib/cjs/array.js @@ -0,0 +1,71 @@ +/** + * @author yutent + * @date 2020/09/16 11:54:31 + */ + +// 判断数组是否包含指定元素 +if (!Array.prototype.includes) { + Object.defineProperty(Array.prototype, 'includes', { + value: function(val) { + for (let it of this) { + if (it === val) { + return true + } + } + return false + }, + enumerable: false, + writable: true + }) +} + +if (!Array.prototype.flat) { + Object.defineProperty(Array.prototype, 'flat', { + value: function(deep = 1) { + var arr = [] + if (deep < 0) { + deep = 0 + } + + deep-- + + for (let it of this) { + if (it === void 0) { + continue + } + if (Array.isArray(it) && deep >= 0) { + arr = arr.concat(it.flat(deep)) + } else { + arr.push(it) + } + } + + return arr + }, + enumerable: false, + writable: true + }) + + // 没有flat, 当然也不会flatMap + Object.defineProperty(Array.prototype, 'flatMap', { + value: function(fn) { + return this.map(fn).flat() + }, + enumerable: false, + writable: true + }) +} + +if (!Array.prototype.item) { + Object.defineProperty(Array.prototype, 'item', { + value: function(num) { + var n = +num + if (n < 0) { + n = this.length + n + } + return this[n] + }, + enumerable: false, + writable: true + }) +} diff --git a/lib/date.js b/lib/cjs/date.js similarity index 89% rename from lib/date.js rename to lib/cjs/date.js index 2ac46fb..0545be1 100644 --- a/lib/date.js +++ b/lib/cjs/date.js @@ -1,17 +1,13 @@ /** - * - * @authors yutent (yutent@doui.cc) - * @date 2017-02-27 22:01:10 - * + * @author yutent + * @date 2020/09/16 11:54:58 */ -'use strict' - //获取当天是本月第几周 if (!Date.isDate) { Object.defineProperty(Date, 'isDate', { value: function(obj) { - return typeof obj === 'object' && obj.getTime ? true : false + return obj && typeof obj === 'object' && obj.getTime ? true : false }, enumerable: false }) @@ -48,7 +44,6 @@ if (!Date.prototype.format) { Object.defineProperty(Date.prototype, 'format', { value: function(str) { str = str || 'Y-m-d H:i:s' - let week = ['Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun'] let dt = { fullyear: this.getFullYear(), year: this.getYear(), @@ -56,7 +51,7 @@ if (!Date.prototype.format) { week: this.getWeek(), month: this.getMonth() + 1, date: this.getDate(), - day: week[this.getDay()], + day: this.getDay() + 1, hours: this.getHours(), minutes: this.getMinutes(), seconds: this.getSeconds() diff --git a/lib/cjs/number.js b/lib/cjs/number.js new file mode 100644 index 0000000..bbdf9cf --- /dev/null +++ b/lib/cjs/number.js @@ -0,0 +1,46 @@ +/** + * @author yutent + * @date 2020/09/16 11:58:40 + */ + +// 简单的数字处理 +// 将安全范围内的数字字符串转为数字类型 +// 否则转为字符串类型 +if (!Number.parse) { + Object.defineProperty(Number, 'parse', { + value: function(val) { + if (typeof val === 'number' || typeof val === 'string') { + val += '' + if (val.startsWith('0') && !val.startsWith('0.')) { + if (val === '0') { + return 0 + } else { + return val + } + } else { + if (isFinite(val)) { + if ( + val >= Number.MIN_SAFE_INTEGER && + val <= Number.MAX_SAFE_INTEGER + ) { + val = +val + } + } + return val + } + } + return val + }, + enumerable: false + }) +} + +// 将字符串转为数字类型 +if (!Number.fromString) { + Object.defineProperty(Number, 'fromString', { + value: function(val) { + return +val || 0 + }, + enumerable: false + }) +} diff --git a/lib/cjs/object.js b/lib/cjs/object.js new file mode 100644 index 0000000..fbffbe6 --- /dev/null +++ b/lib/cjs/object.js @@ -0,0 +1,23 @@ +/** + * @author yutent + * @date 2020/09/16 12:07:09 + */ + +/** + * [ 判断对象/数组是否为空] + * eg. + * Object.empty(obj/arr) + */ +if (!Object.empty) { + Object.defineProperty(Object, 'empty', { + value: function(obj) { + try { + for (let i in obj) { + return false + } + } catch (e) {} + return true + }, + enumerable: false + }) +} diff --git a/lib/promise.js b/lib/cjs/promise.js similarity index 70% rename from lib/promise.js rename to lib/cjs/promise.js index e96939e..abbd882 100644 --- a/lib/promise.js +++ b/lib/cjs/promise.js @@ -1,8 +1,6 @@ /** - * - * @authors yutent (yutent@doui.cc) - * @date 2018-05-25 00:29:03 - * @version $Id$ + * @author yutent + * @date 2020/09/16 12:09:06 */ if (!Promise.defer) { diff --git a/lib/string.js b/lib/cjs/string.js similarity index 91% rename from lib/string.js rename to lib/cjs/string.js index 987b561..d3cdaa0 100644 --- a/lib/string.js +++ b/lib/cjs/string.js @@ -1,12 +1,8 @@ /** - * - * @authors yutent (yutent@doui.cc) - * @date 2017-02-27 22:01:10 - * + * @author yutent + * @date 2020/09/16 12:09:15 */ -'use strict' - //类似于Array 的splice方法 if (!String.prototype.splice) { Object.defineProperty(String.prototype, 'splice', { @@ -153,3 +149,17 @@ if (!String.prototype.padStart) { enumerable: false }) } + +if (!String.prototype.item) { + Object.defineProperty(String.prototype, 'item', { + value: function(num) { + var n = +num + if (n < 0) { + n = this.length + n + } + return this[n] + }, + enumerable: false, + writable: true + }) +} diff --git a/lib/esm/array.mjs b/lib/esm/array.mjs new file mode 100644 index 0000000..fec45d9 --- /dev/null +++ b/lib/esm/array.mjs @@ -0,0 +1,55 @@ +/** + * @author yutent + * @date 2020/09/16 11:54:31 + */ + +if (!Array.prototype.flat) { + Object.defineProperty(Array.prototype, 'flat', { + value: function(deep = 1) { + var arr = [] + if (deep < 0) { + deep = 0 + } + + deep-- + + for (let it of this) { + if (it === void 0) { + continue + } + if (Array.isArray(it) && deep >= 0) { + arr = arr.concat(it.flat(deep)) + } else { + arr.push(it) + } + } + + return arr + }, + enumerable: false, + writable: true + }) + + // 没有flat, 当然也不会flatMap + Object.defineProperty(Array.prototype, 'flatMap', { + value: function(fn) { + return this.map(fn).flat() + }, + enumerable: false, + writable: true + }) +} + +if (!Array.prototype.item) { + Object.defineProperty(Array.prototype, 'item', { + value: function(num) { + var n = +num + if (n < 0) { + n = this.length + n + } + return this[n] + }, + enumerable: false, + writable: true + }) +} diff --git a/lib/esm/date.mjs b/lib/esm/date.mjs new file mode 100644 index 0000000..13bcc15 --- /dev/null +++ b/lib/esm/date.mjs @@ -0,0 +1,88 @@ +/** + * @author yutent + * @date 2020/09/16 11:54:58 + */ + +//获取当天是本月第几周 +if (!Date.isDate) { + Object.defineProperty(Date, 'isDate', { + value: function(obj) { + return obj && typeof obj === 'object' && obj.getTime ? true : false + }, + enumerable: false + }) +} + +if (!Date.prototype.getFullWeek) { + //获取当天是本年度第几周 + Object.defineProperty(Date.prototype, 'getFullWeek', { + value: function() { + let thisYear = this.getFullYear() + let that = new Date(thisYear, 0, 1) + let firstDay = that.getDay() + let numsOfToday = (this - that) / 24 / 360 / 1000 + return Math.ceil((numsOfToday + firstDay) / 7) + }, + enumerable: false + }) + + //获取当天是本月第几周 + Object.defineProperty(Date.prototype, 'getWeek', { + value: function() { + let today = this.getDate() + let thisMonth = this.getMonth() + let thisYear = this.getFullYear() + let firstDay = new Date(thisYear, thisMonth, 1).getDay() + return Math.ceil((today + firstDay) / 7) + }, + enumerable: false + }) +} + +//时间格式化 +if (!Date.prototype.format) { + Object.defineProperty(Date.prototype, 'format', { + value: function(str) { + str = str || 'Y-m-d H:i:s' + var dt = { + fullyear: this.getFullYear(), + year: this.getYear(), + fullweek: this.getFullWeek(), + week: this.getWeek(), + month: this.getMonth() + 1, + date: this.getDate(), + day: this.getDay() + 1, + hours: this.getHours(), + minutes: this.getMinutes(), + seconds: this.getSeconds() + } + var reg = null + + dt.g = dt.hours > 12 ? dt.hours - 12 : dt.hours + + reg = { + Y: dt.fullyear, + y: dt.year, + m: dt.month < 10 ? '0' + dt.month : dt.month, + n: dt.month, + d: dt.date < 10 ? '0' + dt.date : dt.date, + j: dt.date, + H: dt.hours < 10 ? '0' + dt.hours : dt.hours, + h: dt.g < 10 ? '0' + dt.g : dt.g, + G: dt.hours, + g: dt.g, + i: dt.minutes < 10 ? '0' + dt.minutes : dt.minutes, + s: dt.seconds < 10 ? '0' + dt.seconds : dt.seconds, + W: dt.fullweek, + w: dt.week, + D: dt.day + } + + for (let i in reg) { + str = str.replace(new RegExp(i, 'g'), reg[i]) + } + return str + }, + enumerable: false + }) +} diff --git a/lib/esm/number.mjs b/lib/esm/number.mjs new file mode 100644 index 0000000..bbdf9cf --- /dev/null +++ b/lib/esm/number.mjs @@ -0,0 +1,46 @@ +/** + * @author yutent + * @date 2020/09/16 11:58:40 + */ + +// 简单的数字处理 +// 将安全范围内的数字字符串转为数字类型 +// 否则转为字符串类型 +if (!Number.parse) { + Object.defineProperty(Number, 'parse', { + value: function(val) { + if (typeof val === 'number' || typeof val === 'string') { + val += '' + if (val.startsWith('0') && !val.startsWith('0.')) { + if (val === '0') { + return 0 + } else { + return val + } + } else { + if (isFinite(val)) { + if ( + val >= Number.MIN_SAFE_INTEGER && + val <= Number.MAX_SAFE_INTEGER + ) { + val = +val + } + } + return val + } + } + return val + }, + enumerable: false + }) +} + +// 将字符串转为数字类型 +if (!Number.fromString) { + Object.defineProperty(Number, 'fromString', { + value: function(val) { + return +val || 0 + }, + enumerable: false + }) +} diff --git a/lib/esm/object.mjs b/lib/esm/object.mjs new file mode 100644 index 0000000..fbffbe6 --- /dev/null +++ b/lib/esm/object.mjs @@ -0,0 +1,23 @@ +/** + * @author yutent + * @date 2020/09/16 12:07:09 + */ + +/** + * [ 判断对象/数组是否为空] + * eg. + * Object.empty(obj/arr) + */ +if (!Object.empty) { + Object.defineProperty(Object, 'empty', { + value: function(obj) { + try { + for (let i in obj) { + return false + } + } catch (e) {} + return true + }, + enumerable: false + }) +} diff --git a/lib/esm/promise.mjs b/lib/esm/promise.mjs new file mode 100644 index 0000000..abbd882 --- /dev/null +++ b/lib/esm/promise.mjs @@ -0,0 +1,15 @@ +/** + * @author yutent + * @date 2020/09/16 12:09:06 + */ + +if (!Promise.defer) { + Promise.defer = function() { + let obj = {} + obj.promise = new Promise((resolve, reject) => { + obj.resolve = resolve + obj.reject = reject + }) + return obj + } +} diff --git a/lib/esm/string.mjs b/lib/esm/string.mjs new file mode 100644 index 0000000..b9fc591 --- /dev/null +++ b/lib/esm/string.mjs @@ -0,0 +1,116 @@ +/** + * @author yutent + * @date 2020/09/16 12:09:15 + */ + +//类似于Array 的splice方法 +if (!String.prototype.splice) { + Object.defineProperty(String.prototype, 'splice', { + value: function(start, len, fill) { + let length = this.length + let argLen = arguments.length + + fill = fill === undefined ? '' : fill + + if (argLen < 1) { + return this + } + + //处理负数 + if (start < 0) { + if (Math.abs(start) >= length) { + start = 0 + } else { + start = length + start + } + } + + if (argLen === 1) { + return this.slice(0, start) + } else { + len -= 0 + + let strl = this.slice(0, start) + let strr = this.slice(start + len) + + return strl + fill + strr + } + }, + enumerable: false + }) +} + +//同php的htmlspecialchars函数 +if (!String.prototype.htmlspecialchars) { + Object.defineProperty(String.prototype, 'htmlspecialchars', { + value: function(sign) { + let str = this.replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + + if (sign === 'ENT_QUOTES') { + return str.replace(/"/g, '"').replace(/'/g, ''') + } else if (sign === 'ENT_NOQUOTES') { + return str + } else { + return str.replace(/"/g, '"') + } + }, + enumerable: false + }) +} + +//htmlspecialchars的还原 +if (!String.prototype.tohtml) { + Object.defineProperty(String.prototype, 'tohtml', { + value: function() { + return this.replace(/</gi, '<') + .replace(/>/gi, '>') + .replace(/"/gi, '"') + .replace(/'/g, "'") + .replace(/&/gi, '&') + }, + enumerable: false + }) +} + +//简单的过滤xss +if (!String.prototype.xss) { + Object.defineProperty(String.prototype, 'xss', { + value: function() { + let str = this.htmlspecialchars('ENT_QUOTES') + str = str + .replace( + /(document\.cookie)|(document\.write)|(\.parentNode)|(window\.location)|(\.innerHTML)/g, + '' + ) + .replace(/(%0[0-8bcef])|(%1[0-9a-f])/g, '') + return str + }, + enumerable: false + }) +} + +// js特殊字符的转义 +if (!String.prototype.escape) { + Object.defineProperty(String.prototype, 'escape', { + value: function() { + return this.replace(/('|"|&|\\|\}|\{|\(|\)|;|=|\,|&)/g, '\\$1') + }, + enumerable: false + }) +} + +if (!String.prototype.item) { + Object.defineProperty(String.prototype, 'item', { + value: function(num) { + var n = +num + if (n < 0) { + n = this.length + n + } + return this[n] + }, + enumerable: false, + writable: true + }) +} diff --git a/lib/number.js b/lib/number.js deleted file mode 100644 index 88a1553..0000000 --- a/lib/number.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * - * @authors yutent (yutent@doui.cc) - * @date 2018-06-29 19:29:19 - * @version $Id$ - */ -'use strict' - -// 简单的数字处理 -// 将安全范围内的数字字符串转为数字类型 -// 否则转为字符串类型 -if (!Number.parse) { - Object.defineProperty(Number, 'parse', { - value: function(val) { - if (typeof val !== 'number' && typeof val !== 'string') { - return val - } - val += '' - if (val.startsWith('0') && !val.startsWith('0.')) { - if (val === '0') { - return 0 - } else { - return val - } - } else { - if (isFinite(val)) { - if ( - val >= Number.MIN_SAFE_INTEGER && - val <= Number.MAX_SAFE_INTEGER - ) { - val = +val - } - } - return val - } - }, - enumerable: false - }) -} diff --git a/lib/object.js b/lib/object.js deleted file mode 100644 index 2600b38..0000000 --- a/lib/object.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * - * @authors yutent (yutent@doui.cc) - * @date 2017-02-27 18:02:56 - * - */ - -'use strict' - -// 对象合并 -if (!Object.prototype.merge) { - Object.defineProperty(Object.prototype, 'merge', { - value: function() { - let args = Array.from(arguments) - if (args.length < 1 || typeof args[0] !== 'object') { - return this - } - args.unshift(this) - - Object.assign.apply(null, args) - return this - }, - enumerable: false, - writable: true - }) -} - -/** - * [ 判断对象/数组是否为空] - * eg. - * Object.empty(obj/arr) - */ -if (!Object.empty) { - Object.defineProperty(Object, 'empty', { - value: function(obj) { - try { - for (let i in obj) { - return false - } - } catch (e) {} - return true - }, - enumerable: false - }) -} diff --git a/package.json b/package.json index 4cddd23..7de86a3 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,13 @@ { "name": "es.shim", - "version": "1.1.2", - "description": "Some shim api that let you can use in all node.js environment", - "keyworks": [ - "es5", - "es6", - "polyfill", - "extend", - "shim" - ], + "version": "2.0.0", + "description": "实现部分新API, 以及一些常用的扩展方法", + "keyworks": ["es5", "es6", "es7", "polyfill", "extend", "shim"], "main": "index.js", + "exports": { + "require": "./index.js", + "import": "./index.mjs" + }, "repository": "https://github.com/yutent/es.shim.git", "author": "yutent", "license": "MIT"