一、Js实现call、apply、bind
1、call
// apply/call/bind的用法
// js模拟它们的实现? 难度
// 给所有的函数添加一个hycall的方法
Function.prototype.hycall = function(thisArg, ...args) {
// 在这里可以去执行调用的那个函数(foo)
// 问题:得可以获取到是哪一个函数执行了hycall
// 1.获取需要被执行的函数
var fn = this
// 2.对thisArg转成对象类型(防止它传入的是非对象类型)
thisArg = (thisArg != null || thisArg != undefined) ? Object(thisArg) : window // 排除null undefined
// 3.调用需要被执行的函数
// fn.call(thisArg)
thisArg.fn = fn
var result = thisArg.fn(...args);
delete thisArg.fn
// 4.将最终的结果返回出去
return result;
// console.log(thisArg,"hycall被调用");
}
function foo() {
console.log("foo函数被执行",this);
}
function sum(sum1, sum2) {
console.log("sum函数被执行",this, sum1, sum2);
return sum1 + sum2
}
// 系统的函数call方法
// foo.call();
// 自己实现的hycall的方法
sum.hycall('1111', 20,30);
var endNum = sum.hycall('1111', 20,30);
console.log(endNum,"最终的结果");
// foo.hycall('1111', 20,30);
Function.prototype.hycall = function(thisArg, ...args) {
var fn = this;
thisArg = (thisArg != null || thisArg != undefined) ? Object(thisArg) : window;
thisArg.fn = fn;
var result = thisArg.fn(...args)
delete thisArg.fn
return result
}
2、apply
// 自己实现hyapply
Function.prototype.hyapply = function(thisArg, argArray) {
// 在这里可以去执行调用的那个函数(foo)
// 问题:得可以获取到是哪一个函数执行了hyapply
// 1.获取需要被执行的函数
var fn = this
// 2.对thisArg转成对象类型(防止它传入的是非对象类型) 0
thisArg = (thisArg != null || thisArg != undefined) ? Object(thisArg) : window // 排除null undefined
argArray = argArray || []
// 3.调用需要被执行的函数
// fn.call(thisArg)
thisArg.fn = fn
var result = thisArg.fn(...argArray);
delete thisArg.fn
// 4.将最终的结果返回出去
return result;
}
function sum(num1, num2) {
console.log("sum被调用", this, num1, num2);
return num1 + num2
}
// 系统调用
// sum.apply("abc",[20,30])
// 自己实现
var result = sum.hyapply("abc",[20, 30])
console.log(result,"最后的结果");
sum.hyapply('abc')
Function.prototype.hyapply = function(thisArg, args) {
var fn = this;
thisArg = (thisArg != null || thisArg != undefined) ? Object(thisArg) : window;
thisArg.fn = fn;
args = args || []
var result = thisArg.fn(...args)
delete thisArg.fn
return result
}
3、bind
// apply/call/bind的用法
// js模拟它们的实现? 难度
// 给所有的函数添加一个hybind的方法
Function.prototype.hybind = function(thisArg, ...argArray) {
// 在这里可以去执行调用的那个函数(foo)
// 问题:得可以获取到是哪一个函数执行了hybind
// 1.获取需要被执行的函数
var fn = this
// 2.对thisArg转成对象类型(防止它传入的是非对象类型)
thisArg = (thisArg != null && thisArg != undefined) ? Object(thisArg) : window // 排除null undefined
function proxyFn(...args) {
// 3.调用需要被执行的函数
thisArg.fn = fn
var finalArgs = [...argArray, ...args]
var result = thisArg.fn(...finalArgs);
delete thisArg.fn
// 4.将最终的结果返回出去
return result;
}
return proxyFn;
}
function sum(sum1, sum2, sum3, num4) {
console.log("sum函数被执行",this, sum1, sum2, sum3, num4);
return sum1 + sum2 + sum3
}
// 系统的函数bind方法
// sum.bind('1111')(20,30,50);
// 自己实现的hybind的方法
// sum.hybind('1111', 20,30);
var endNum = sum.hybind('1111', 20,30, 50);
var endSum = endNum(60, 70)
console.log(endSum,"最终的结果");
Function.prototype.hybind = function(thisArg, ...argArray) {
var fn = this;
thisArg = (thisArg != null || thisArg != undefined) ? Object(thisArg) : window
function proxyFn(...args) {
thisArg.fn = fn
var finalArgs = [...argArray, ...args]
var result = thisArg.fn(...finalArgs)
delete thisArg.fn
return result
}
return proxyFn
}
二、arguments解析
1.arguments基本使用
function foo(num1, num2, num3) {
// 类数组对象中(长得像是一个数组,本质上是一个对象) arguments
console.log(arguments);
// 常见的对arguments的操作十三个
// 1.获取参数的长度
console.log(arguments.length);
// 2.根据索引值获取某一个参数
console.log(arguments[1]);
// 3. callee获取当前arguments所在的函数
console.log(arguments.callee);
console.log(num1, num2, num3 );
}
foo(10, 20, 30, 40, 50)
2.argument转成array类型数据
Array中的slice实现:
function foo(num1, num2) {
console.log(arguments);
// 1.自己遍历
// var newArr = []
// for (var i = 0; i < arguments.length; i++) {
// newArr.push(arguments[i]*10);
// }
// console.log(newArr);
// 2.arguments转成数组类型
// var newArr2 = Array.prototype.slice.call(arguments)
// console.log(newArr2);
// var newArr3 = [].slice.call(arguments)
// console.log(newArr3);
// ES6语法
// var newArr4 = Array.from(arguments)
// console.log(newArr4);
var newArr5 = [...arguments]
console.log(newArr5);
}
foo(10, 20, 30, 40)
// 额外补充的知识点: Array中的slice实现
// Array.prototype.hyslice = function(start, end) {
// var arr = this
// start = start || 0
// end = end || arr.length
// var newArray = []
// for (var i = start; i < end; i++) {
// newArray.push(arr[i])
// }
// return newArray
// }
// var newArray = Array.prototype.hyslice.call(["aaaa", "bbb", "cccc"], 1, 3)
// console.log(newArray)
// var names = ["aaa", "bbb", "ccc", "ddd"]
// console.log(names.slice(1, 3));
Array.prototype.hyslice = function(start, end) {
var arr = this
start = start || 0
end = end || arr.length
var newArray = []
for (var i = start; i < end; i++) {
newArray.push(arr[i])
}
return newArray
}
1、 var newArr2 = Array.prototype.slice.call(arguments)
2、 var newArr3 = [].slice.call(arguments)
3、 var newArr4 = Array.from(arguments)
4、 var newArr5 = […arguments]
3.箭头函数中没有arguments
// 1.案例一:
// var foo = () => {
// console.log(arguments);
// }
// function bar() {
// console.log(arguments);
// }
// foo()
// 2.案例二:
// function foo() {
// var bar = () => {
// console.log(arguments)
// }
// return bar
// }
// var fn = foo(123)
// fn()
// 3.案例三:
var foo = (num1, num2, ...args) => {
console.log(args)
}
foo(10, 20, 30, 40, 50)