目录
1、手写instanceof
请补全JavaScript代码,要求以Boolean的形式返回第一个实例参数是否在第二个函数参数的原型链上。
instanceof:用来判断复杂数据类型
完整代码:
方法1:
核心步骤有:
- 获取首个对象参数的原型对象
- 获取Fn函数的原型对象
- 进入死循环,当两个参数的原型对象相等时返回true
- 当两个参数的原型对象不相等时获取首个对象参数原型的原型并且循环该步骤直到null时返回false
const _instanceof = (target, Fn) => {
// 补全代码
// target实例的类型是object
if (target === null || typeof target !== 'object') {
return false
}
let proto = target.__proto__
let prototype = Fn.prototype
while (true) {
if (proto === Fn.prototype) return true
if (proto === null) return false
proto = proto.__proto__
}
}
方法2:
const _instanceof = (target, Fn) => {
// 补全代码
// target实例的类型是object
if (target === null || typeof target !== 'object') {
return false;
}
// Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。
let proto = Object.getPrototypeOf(target);
while (true) {
if (proto === null) return false;
if (proto === Fn.prototype) return true;
// 如果proto !== Fn.prototype,则获取proto的原型重新进行判断(逐渐收缩proto)
proto = Object.getPrototypeOf(proto);
}
}
2、手写Array.map
请补全JavaScript代码,要求实现Array.map函数的功能且该新函数命名为"_map"。
输入:[1,2]._map(i => i * 2)
输出:[2,4]
写代码前,我们先了解Array.map是干什么的
语法:array.map(callbackFn(currentValue,index,arr), thisValue)
解释:Array.map
函数接收一个回调函数,该回调函数又能接收三个参数currentValue,index,arr。
currentvalue:表示数组的当前元素项,必须的参数
index:表示的当前元素下标,可选参数
arr:表示当前元素所属的数组,可选参数
thisValue表示执行回调函数callback()时的this指向。可选参数。当不写时,则默认是指向window全局
map() 方法返回一个新数组,数组中的元素为回调函数返回后的值。
手撕核心步骤有:
- 判断参数是否为函数,如果不是则直接返回
- 创建一个空数组用于承载新的内容
- 循环遍历数组中的每个值,分别调用函数参数,将返回值添加进空数组中
- 返回新的数组
完整代码:
// 因为要将_map挂载到Array上,所以要调用原型链的方法Array.prototype._map
Array.prototype._map = function(Fn) {
if (typeof Fn !== 'function') return;
const array = this;
const newArray = new Array(array.length);
for (let i=0; i<array.length; i++) {
let result = Fn.call(arguments[1], array[i], i, array);
newArray[i] = result;
}
return newArray;
}
3、手写Array.filter
请补全JavaScript代码,要求实现Array.filter函数的功能且该新函数命名为"_filter"。
输入:[1,2]._filter(i => i>1)
输出:[2]
写代码前,我们先了解Array.filter是干什么的
语法:array.filter(callbackFn(currentValue,index,arr))
解释:Array.filter
函数接收一个回调函数,该回调函数又能接收三个参数currentValue,index,arr。
currentvalue:表示数组的当前元素
index:表示正在处理当前元素的索引
arr:表示当前元素所属的数组
filter() 方法返回一个新数组,数组中的元素为通过回调函数返回后的值。
核心步骤有:
- 判断参数是否为函数,如果不是则直接返回
- 创建一个空数组用于承载新的内容
- 循环遍历数组中的每个值,分别调用函数参数,将满足判断条件的元素添加进空数组中
- 返回新的数组
完整代码:
Array.prototype._filter = function(Fn) {
if (typeof Fn !== 'function') return;
const array = this;
const newArray = [];
for (let i=0; i<array.length; i++) {
const result = Fn.call(arguments[1], array[i], i, array);
// 要判断是否存在
result && newArray.push(array[i]);
}
return newArray;
}
4、手写Array.reduce
请补全JavaScript代码,要求实现Array.reduce函数的功能且该新函数命名为"_reduce"。
输入:[1,2,3]._reduce((left, right) => left + right)
输出:6
写代码前,我们先了解Array.reduce是干什么的
语法:array.reduce(callbackFn(previousValue,currentValue,currentIndex,arr),initialValue)
解释:Array.filter
函数接收一个回调函数,该回调函数又能接收四个参数:
previousValue:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值为initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]。
currentValue:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]。
currentIndex:数组中正在处理的元素的索引。若指定了初始值initialValue,则起始索引号为 0,否则从索引 1 起始。
array:用于遍历的数组。
initialValue: (可选)
作为第一次调用 callbackFn函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。
总结Array.reduce的特点有:
- 接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
- 可以接收一个初始值,当没有初始值时,默认初始值为数组中的第一项
实现该函数的核心步骤有:
- 在Array的原型对象上添加”_reduce“函数
- ”_reduce“函数第一个参数为回调函数,第二个参数为初始值
- 进入数组长度的循环体中
- 当初始值为空时,首个被加数为数组的第一项
- 当初始值不为空时,首个被加数为初始值
完整代码:
Array.prototype._reduce = function(fn, prev) {
for(let i=0 ; i<this.length ; i++) {
if(prev === undefined) {
prev = fn(this[i], this[i+1], i+1, this);
++i;
} else {
prev = fn(prev, this[i], i, this);
}
}
return prev;
}