instanceof
// 如果 target 为基本数据类型直接返回 false
// 判断 Fn.prototype 是否在 target 的隐式原型链上
const _instanceof = (target, fn) => {
if ((typeof target !== 'object' && typeof target !== 'function') || target === null) return false
let proto = target.__proto__
while (true) {
if (proto === null) return false
if (proto === fn.prototype) return true
proto = proto.__proto__
}
}
function A() {}
const a = new A()
console.log(_instanceof(a, A)); // true
console.log(_instanceof(1, A)); // false
map
// map 中的 exc 接受三个参数,分别是: 元素值、元素下标和原数组
// map 返回的是一个新的数组,地址不一样
// 这里不能直接使用箭头函数,否则无法访问到 this
Array.prototype._map = function (exc) {
const result = []
this.forEach((item, index, arr) => {
result[index] = exc(item, index, arr)
return result
})
}
const a = new Array(2).fill(2)
console.log(a.map((item, index, arr) => item*index + 1)); // [1,3]
console.log(a._map((item, index, arr) => item*index + 1)); // [1,3]
filter
// filter 中的 exc 接受三个参数,与map一致,主要实现的是数组的过滤功能,会根据 exc 函数的返回值来判断是否“留下”该值。
// filter 返回的是一个新的数组,地址不一致。
Array.prototype._filter = function (exc) {
const result = []
this.forEach((item, index, arr) => {
if (exc(item, index, arr)) {
result.push(item)
}
})
return result
}
const b = [1, 3, 4, 5, 6, 2, 5, 1, 8, 20]
console.log(b._filter(item => item % 2 === 0)); // [4, 6, 2, 8, 20]
reduce
// reduce 接受两个参数,第一个为 exc 函数,第二个为初始值,如果不传默认为 0
// reduce 最终会返回一个值,当然不一定是 Number 类型的,取决于你是怎么计算的,每次的计算结果都会作为下次 exc 中的第一个参数
Array.prototype._reduce = function (exc, initial = 0) {
let result = initial
this.forEach(item => {
result = exc(result, item)
})
return result
}
const b = [1, 3, 4, 5, 6, 2, 5, 1, 8, 20]
console.log(b.reduce((pre, cur) => pre + cur, 0));
console.log(b._reduce((pre, cur) => pre + cur, 0));
create
// Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的隐式原型(__proto__)
// __proto__属性指向的就是他的构造函数的prototype
Object.prototype._create = function (proto) {
const Fn = function () {}
Fn.prototype = proto
return new Fn()
}
function A() {}
const obj = Object.create(A)
const obj2 = Object._create(A)
console.log(obj.__proto__ === A); // true
console.log(obj2.__proto__ === A); // true
new关键字
// new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
const _new = function(constructor) {
const obj = {}
obj.__proto__ = constructor.prototype
const result = constructor.call(obj)
return typeof result === 'object' && result !== null ? result : obj
}