-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我要懂系列-call和apply #15
Labels
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
看了冴羽大神的JavaScript深入之call和apply的模拟实现有所收获,所以也写了篇总结下,并且特地开了个系列,希望能够整理下自己的所学
call
apply
相同点:
区别:
模拟实现:
第一个条件很简单,判断下 isThis 的类型即可
第二个条件和第三个条件是一样的,call 的参数我们需要处理下,因为我们预期不到它的参数个数
我们从第二个参数开始遍历一遍 arguments,然后放到一个数组里面去
但是最关键的调用怎么办呢,怎么改变 this 的指向,一般来说谁调用谁就是 this,我们要想改变 this,那么就要用传递进来的 isThis 来调用
这样的话就改变了 this 的指向,之后再 delete 掉,就 ok 了,但是这里会有一个问题,如果传递进来的是值类型呢,值类型我们是不能给它添加属性和方法的,所以
isThis.fn()
肯定会提示isThis.fn is not a function
,这里我们可以想一想值类型也是可以像对象一样有属性和方法的,并且可以添加属性和方法,但是为什么赋值完后就找不到呢这里要说下包装类型了,值类型按理说是不可能有自己的属性和方法的,但是考虑到有时候需要处理下杂七杂八的琐事,所以当我们访问或者赋值的时候,它会临时给我们创建一个对应的包装对象,在我们访问或者赋值结束后那么这个包装对象就会被清理掉,那么我们就可以这样做,来模拟下包装对象
恩,这样一来就差不多了,接下来看看传参,args 的元素才是我们想要的参数,所以怎么拆开
使用 eval,得益于 eval 强大的能力,我们可以把字符串当做 js 代码来执行,并且可以得到返回值,完美
但是这里会有一个问题,如果参数是个对象,那么 eval 对参数 toString 后我们我们就得不到想要的参数了,所以这里改造下,因为 eval 可以动态的改变作用域
这里我们用 args 存放着 arguments[1] arguments[1]... 这样的字符串,那么 eval 执行的时候会在上下文查找并绑定所需要的变量,这样就可以实现参数传递了
完整代码:
The text was updated successfully, but these errors were encountered: