functionobjectFactory() { var obj = newObject() Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; var ret = Constructor.apply(obj, arguments); // ret || obj 这里这么写考虑了构造函数显示返回 null 的情况 returntypeof ret === 'object' ? ret || obj : obj; };
使用:
1 2 3 4 5 6 7
functionperson(name, age) { this.name = name this.age = age } let p = objectFactory(person, '布兰', 12) console.log(p) // { name: '布兰', age: 12 }
instanceof
instanceof 就是判断构造函数的 prototype 属性是否出现在实例的原型链上。
1 2 3 4 5 6 7 8 9 10 11
functioninstanceOf(left, right) { let proto = left.__proto__ while (true) { if (proto === null) returnfalse if (proto === right.prototype) { returntrue } proto = proto.__proto__ } }
Object.create2 = function(proto, propertyObject = undefined) { if (typeof proto !== 'object' && typeof proto !== 'function') { thrownewTypeError('Object prototype may only be an Object or null.') if (propertyObject == null) { newTypeError('Cannot convert undefined or null to object') } functionF() {} F.prototype = proto const obj = new F() if (propertyObject != undefined) { Object.defineProperties(obj, propertyObject) } if (proto === null) { // 创建一个没有原型对象的对象,Object.create(null) obj.__proto__ = null } return obj }
Object.assign()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Object.assign2 = function(target, ...source) { if (target == null) { thrownewTypeError('Cannot convert undefined or null to object') } let ret = Object(target) source.forEach(function(obj) { if (obj != null) { for (let key in obj) { if (obj.hasOwnProperty(key)) { ret[key] = obj[key] } } } }) return ret }
var rx_one = /^[\],:{}\s]*$/; var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
if ( rx_one.test( json.replace(rx_two, "@") .replace(rx_three, "]") .replace(rx_four, "") ) ) { var obj = eval("(" +json + ")"); }
Function.prototype.apply2 = function (context, arr) { var context = context || window; const fnSymbol = Symbol('fn'); context.fnSymbol = this;
var result; if (!arr) { result = context.fn(); } else { var args = []; for (var i = 0, len = arr.length; i < len; i++) { args.push('arr[' + i + ']'); } result = eval('context.fnSymbol(' + args + ')') }
delete context.fnSymbol return result; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 似乎更简洁 Function.prototype.myApply = function(context) { if (typeofthis !== 'function') { thrownewTypeError('Error'); } context = context || window; context.fn = this; let result; if (arguments[1]) { result = context.fn(...arguments[1]); } else { result = context.fn(); } delete context.fn; return result; }
bind
bind 方法会创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
// 似乎更简洁 Function.prototype.myBind = function (context) { if (typeofthis !== 'function') { thrownewTypeError('Error'); } var _this = this; var args = Array.prototype.slice.call(arguments, 1); returnfunction () { var bindArgs = Array.prototype.slice.call(arguments); _this.apply(context, args.concat(bindArgs)); } }
数组原型方法
forEach
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Array.prototype.forEach2 = function(callback, thisArg) { if (this == null) { thrownewTypeError('this is null or not defined') } if (typeof callback !== "function") { thrownewTypeError(callback + ' is not a function') } const O = Object(this) // this 就是当前的数组 const len = O.length >>> 0// 后面有解释 let k = 0 while (k < len) { if (k in O) { callback.call(thisArg, O[k], k, O); } k++; } }
- Array.prototype.forEach2 = function(callback, thisArg) { + Array.prototype.map2 = function(callback, thisArg) { if (this == null) { throw new TypeError('this is null or not defined') } if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } const O = Object(this) const len = O.length >>> 0 - let k = 0 + let k = 0, res = [] while (k < len) { if (k in O) { - callback.call(thisArg, O[k], k, O); + res[k] = callback.call(thisArg, O[k], k, O); } k++; } + return res }
- Array.prototype.forEach2 = function(callback, thisArg) { + Array.prototype.filter2 = function(callback, thisArg) { if (this == null) { throw new TypeError('this is null or not defined') } if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } const O = Object(this) const len = O.length >>> 0 - let k = 0 + let k = 0, res = [] while (k < len) { if (k in O) { - callback.call(thisArg, O[k], k, O); + if (callback.call(thisArg, O[k], k, O)) { + res.push(O[k]) + } } k++; } + return res }
- Array.prototype.forEach2 = function(callback, thisArg) { + Array.prototype.some2 = function(callback, thisArg) { if (this == null) { throw new TypeError('this is null or not defined') } if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function') } const O = Object(this) const len = O.length >>> 0 let k = 0 while (k < len) { if (k in O) { - callback.call(thisArg, O[k], k, O); + if (callback.call(thisArg, O[k], k, O)) { + return true + } } k++; } + return false }
Array.prototype.reduce2 = function(callback, initialValue) { if (this == null) { thrownewTypeError('this is null or not defined') } if (typeof callback !== "function") { thrownewTypeError(callback + ' is not a function') } const O = Object(this) const len = O.length >>> 0 let k = 0, acc if (arguments.length > 1) { acc = initialValue } else { // 没传入初始值的时候,取数组中第一个非 empty 的值为初始值 while (k < len && !(k in O)) { k++ } if (k > len) { thrownewTypeError( 'Reduce of empty array with no initial value' ); } acc = O[k++] } while (k < len) { if (k in O) { acc = callback(acc, O[k], k, O) } k++ } return acc }