一、call原理
一、call理论
概念:call()方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。
语法:fun.call(thisArg, arg1, arg2, ...)
返回值:使用调用者提供的this值的参数调用该函数的返回值,如果没有返回值,为undefined。
作用:call就是将函数绑定到另外一个对象上去运行,且是自动调用;另外还可以改变当前函数的this的指向。
小Tip:call方法与apply方法本质差不多,就仅仅是参数传递时有所不同,apply需要以数组形式传参,call方法就直接在对象后直接传递就行啦!
二、call原理
1)call简单应用
2)call方法封装
第一步:对象借用函数,将函数绑定到对象上
第二步:函数中参数传递
<script>
function f(a,b) {
console.log("f..."+a+b)//字符串拼接
console.log(a+b)
}
Function.prototype.call = function (context) {
context.fn = this//给obj对象加上借用函数
// 函数传参
console.log(arguments)//Arguments(3) [{…}, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
let args = []
// 去掉首参,伪数组进行遍历,推到新数组中
for(let i = 1;i<arguments.length;i++){
args.push('arguments['+ i +']')//以字符串形式推进去
}
// console.log(args)//["arguments[1]", "arguments[2]"]
// eval是全局函数,计算某个字符串,并执行其中的代码
// 将括号中当做js代码,然后调用fn传递参数为args
let r = eval('context.fn('+args+')')
delete context.fn;//清空借用的函数
return r
}
let obj = {
name: "wangcai"
}
f.call(obj,2,3)
console.dir(obj)//{name:"wangcai"}
</script>
第三步:借用函数存在返回值及当对象无借用函数时
<script>
function f(a,b) {
return a+b
}
Function.prototype.call = function (context) {
// context为空,即没有内容就去借用window函数
context = context ? Object(context):window
context.fn = this//给obj对象加上借用函数
// 函数传参
let args = []
for(let i = 1;i<arguments.length;i++){
args.push('arguments['+ i +']')//以字符串形式推进去
}
let r = eval('context.fn('+args+')')
delete context.fn;//清空借用的函数
// return r
}
let obj = {
name: "wangcai"
}
// 当借用函数存在返回值,需要在封装函数中也返回结果
// 还需要打印才能得到函数返回值
console.log(f.call(obj,2,3))//5
console.dir(obj)//{name:"wangcai"}
</script>
最后:call原理完整代码,捎带着对应代码的注释
<script>
function f(a, b) {
// console.log("f..........")
// console.log(a + b)
return a + b + 7//不要忘记借用函数存在返回值时
}
Function.prototype.call = function (context) {
// 注意context为空时,借用函数属于window
context = context ? Object(context):window
// 让对象指向借用函数
context.fn = this
// 排除首参,将参数接收存到数组,遍历每一项
let args = []
for (i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']')
}
// 计算字符串,解析()中代码得到结果
let r = eval('context.fn(' + args + ')')
// 删除借用函数
delete context.fn
return r
}
let obj = {
name: "tanni"
}
console.log(f.call(obj, 2, 3))
</script>
二、bind原理
一、bind理论
bind本质上要返回一个新的函数,需要手动调用它才可执行。
bind作用可分为三大点:1)bind返回一个绑定后的函数;2)改变this指向;3)函数不会自动调用,需要手动执行。
二、bind原理
1)bind简单应用
第一步:bind函数本质上是返回一个函数,需要自己手动调用,它会被立即执行,借用了call函数或者apply函数。
第二步:函数参数传递(bind后的参数传递)
第三步:函数参数传递(新函数调用处的参数)
三、new原理
一、new理论
new是关键字,不是方法,它只能通过函数来实现,new的本质就是得到new上的那个类上面的方法和属性。
二、new原理
1)new简单应用
2)new关键字封装
第一步:获取到要new上的类,利用shift将其筛选出来的。
第二步:得到new完类之后的对象上,存在的方法和属性。
第三步:完善new关键字的理论(当new上的那个类返回一个空对象时)