call方法的实现
Function.prototype.myCall = function (context) {
//this 调用的函数
//context 调用函数的对像
// 判断this是否为函数
if (typeof this !== 'function') {
throw TypeError('Error')
}
context = context || window
//声明一个Symbol 防止fn被占用
const fn = Symbol('fn')
//将函数添加成为contxt 对象的方法被调用
context[fn] = this
//获取参数
//const args = Array.prototype.slice.call(arguments, 1)
//const args = Array.from(arguments).slice(1)
const args = [...arguments].slice(1)
//调用返回结果
const result = context[fn](...args)
//删除方法
delete context[fn]
//返回结果
return result
}
apply方法实现
Function.prototype.myApply = function (context){
if (typeof this !== 'function') {
throw TypeError('Error')
}
context = context || window
const args = arguments[1]
const fn = Symbol('fn')
context[fn] = this
const result = context[fn](...args)
delete context[fn]
return result
}
bind方法实现
Function.prototype.myBind = function (context){
if (typeof this !== 'function') {
throw TypeError('Error')
}
const args = [...arguments].slice(1)
let _this = this
return function F(){
if (this instanceof F) {
return new _this(...args, ...arguments)
} else {
return _this.call(context, ...args, ...arguments)
}
}
}
//例题
function print(age) {
console.log(this.name+ "" + age)
}
let obj = {
name: "李华"
}
print.myCall(obj,1,2,3) //李华1
print.myApply(obj,[3,2,1]) //李华3
new方法实现
function myNew(){
//创建一个新对象
let obj = new Object()
//获取到构造函数
let Constructor = Array.prototype.shift.call(arguments)
//将对象的__proto__(隐形原型属性) == 构造函数的 prototype 显示原型属性
obj.__proto__ = Constructor.prototype
//将构造函数作为对象的方法被调用
let ret = Constructor.apply(obj, arguments)
// 如果构造函数返回值是对象则返回这个对象,如果不是对象则返回新的实例对象
return typeof ret === "object" && ret !== null ? ret : obj
}
//例题:
// ========= 无返回值 =============
// const testNewFun = function(name) {
// this.name = name;
// };
//
// const newObj = myNew(testNewFun, 'foo');
//
// console.log(newObj); // { name: "foo" }
// console.log(newObj instanceof testNewFun); // true
// ========= 有返回值 =============
const testNewFun = function(name) {
this.name = name;
return {};
};
const newObj = myNew(testNewFun, 'foo');
console.log(newObj); // {}
console.log(newObj instanceof testNewFun); // false
reduce实现
Array.prototype.myReduce = function (callbackFn){
let o = this
let k = 0,
kPresent = false,
accumulator,
initialValue = arguments.length > 0 ? arguments[1] : undefined,
len = this.length
if (typeof callbackFn !== 'function') {
throw TypeError('Error')
}
if (len === 0 && initialValue !== undefined) {
throw TypeError('Error')
}
if (initialValue !== undefined) {
accumulator = initialValue
} else {
accumulator = o[k]
++k
}
while (k < len) {
kPresent = o.hasOwnProperty(k)
if (kPresent) {
accumulator = callbackFn.apply(undefined, [accumulator, o[k], k, o])
}
++k
}
return accumulator
}
const rReduce = ['1', null, undefined, , 3, 4].reduce((a, b) => a + b, 3);
const mReduce = ['1', null, undefined, , 3, 4].myReduce((a, b) => a + b, 3);
console.log(rReduce, mReduce)