<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>call,apply,bind的实现</title>
</head>
<body>
<script>
//call的实现
Function.prototype.myCall = function (ctx, ...args) {
let ctxtype = Object.prototype.toString.call(ctx).slice(8,-1).toLowerCase()
const fn = Symbol('fn') // 声明一个独有的Symbol属性, 防止fn覆盖已有属性
if(ctxtype!='object'){
ctx = window
}
ctx[fn] = this;//函数挂在ctx上
const result = ctx[fn](...args) // 执行当前函数
delete ctx[fn] // 删除我们声明的fn属性
return result // 返回函数执行结果
}
let obj1 = {
name:'tom'
}
function foo(p1,p2){
console.log(this)
console.log(p1,p2)
return 'finish foo'
}
foo.myCall(obj1,'wowo1','omom1')
//applay的实现
Function.prototype.myapply = function (ctx,args) {
let ctxtype = Object.prototype.toString.call(ctx).slice(8,-1).toLowerCase()
const fn = Symbol('fn') // 声明一个独有的Symbol属性, 防止fn覆盖已有属性
if(!Array.isArray(args)){
throw TypeError('the second param should be a array')
}
if(ctxtype!='object'){
ctx = window
}
ctx[fn] = this;//函数挂在ctx上
const result = ctx[fn](...args) // 执行当前函数
delete ctx[fn] // 删除我们声明的fn属性
return result // 返回函数执行结果
}
let obj2 = {
name:'jack'
}
function bar(p1,p2){
console.log(this)
console.log(p1,p2)
return 'finish bar'
}
bar.myapply(obj2,['wowo2','omom2'])
//bind的实现
Function.prototype.mybind = function (ctx,...args) {
let ctxtype = Object.prototype.toString.call(ctx).slice(8,-1).toLowerCase()
const fn = Symbol('fn') // 声明一个独有的Symbol属性, 防止fn覆盖已有属性
let that = this;
return function(){
if(ctxtype!='object'){
ctx = window
}
ctx[fn] = that;//函数挂在ctx上
const result = ctx[fn](...args) // 执行当前函数
delete ctx[fn] // 删除我们声明的fn属性
return result // 返回函数执行结果
}
}
let obj3 = {
name:'bob'
}
function test(p1,p2){
console.log(this)
console.log(p1,p2)
return 'finish test'
}
let testbind = test.mybind(obj3,'wowo3','omom3')
testbind()
</script>
</body>
</html>