JS手写call,apply,bind方法
这三个方法的作用说白了就是改变this指向,非常简单,但是手写需要搞清楚原理。
这里用call作为例子
var test = {
value: 11
}
function bar() {
console.log(this.value)
}
bar.call(test) //11
call改变了this指向,指向了test
bar函数执行
手写模拟这种效果,怎么将bar的this指向test呢?
var test = {
value: 11,
function bar() {
console.log(this.value)
}
}
test.bar()
这样效果便和上面一样了,但是白白给test加了一个属性这是不行的,所以最后需要删除它。
所以模拟步骤可以分为三步:
1.将函数设为对象的属性
2.执行函数
3.删除函数
所以代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
Function.prototype.call2 = function(context) {
context.fn = this //this指向调用者,结合下文即为bar
context.fn() //指向函数
delete context.fn //删除函数
}
var test = {
value: 11
}
function bar() {
console.log(this.value)
}
bar.call2(test) //11
</script>
</body>
</html>
但是仔细一想call函数是可以传参的,于是稍作修改:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
Function.prototype.call2 = function(context) {
context.fn = this
let rest = [...arguments].slice(1) //用slice方法获取第二个开始的参数作为参数数组
let result = context.fn(...rest) //传参数组
delete context.fn
}
var test = {
value: 11
}
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
bar.call2(test,'lwhdsb',18)
//lwhdsb
//18
//11
</script>
</body>
</html>
使用arguments属性和slice方法可以截取数组
需要注意
this传null或者undefined时,将是window,(node环境是global)
函数有返回值
所以再次稍作修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
Function.prototype.call2 = function(context) {
if(!context){
context = typeof window === 'undefined' ? global : window
}
context.fn = this
let rest = [...arguments].slice(1) //用slice方法获取第二个开始的参数作为参数数组
let result = context.fn(...rest) //传参数组
delete context.fn
return result
}
var test = {
value: 11
}
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
bar.call2(test,'lwhdsb',18)
//lwhdsb
//18
//11
</script>
</body>
</html>
就是最终版本,其他两个也和这个思路大差不差,就省略了
原文地址:https://blog.csdn.net/2301_80659102/article/details/142375754
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!