作用域
- 全局作用域 - window
- 局部作用域 - js 当中只有函数具备块级作用域
异同:
改变函数体内 this 的指向。
不同之处:
- call 严格模式
- call 非严格模式
- apply 和 call 基本上一致,唯一区别在于传参方式
- bind 语法和 call 一模一样,区别在于立即执行还是等待执行,bind 不兼容 IE6~8。
案例
函数是在哪里被谁调用的。也就是说 this 指向谁,跟函数在哪里定义没有关系,而是取决于被谁调用。
1 | function foo() { |
默认情况,在非严格模式下,this 指向全局对象,在浏览器中就是 window
严格模式,this 为 undefined
隐式绑定,foo 作为 o2 的方法来调用,就指向 o2
1 | function foo() { |
通过 call、apply 或者 bind 调用的,那么这种调用就是显式绑定这种绑定中,this 的指向就是这三个函数中传递的第 一个参数。
call:
当前实例(函数)通过原型链查找机制找到 function.prototpye 上 call 方法。
把找到的 call 方法执行 当 call 方法执行的时候,内部处理了一些事情 1.首先把要操作的函数中的 this 关键字变为 call 方法第一个传递的实参 2.把 call 方法第二个及之后的实参获取到 3.把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数
call 中细节
在非严格模式下
如果不传参数,或者第一个参数是 null 或 nudefined,this 都指向 window
1 | const fn = function (a, b) { |
在严格模式下
第一个参数是谁,this 就指向谁,不传就为 undefined
1 | ; |
apply
apply 把需要传递给 fn 的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给 fn 一个个的传递
1 | fn.call(obj, 1, 2); |
bind
bind 与 call 的 区别在一个是立即执行函数,一个是等待执行
1 | document.onclick = fn.call(obj); |
1 | document.onclick = fn.bind(obj); |
实现 call
1 | Function.prototype.myCall = function (obj, ...args) { |
实现 apply
1 | Function.prototype.myCall = function (context = window, args) { |
实现 bind
总的来说 bind 有如下三个功能点:
- 改变原函数的 this 指向,即绑定上下文,返回原函数的拷贝。
- 当 绑定函数 被调用时,bind 的额外参数将置于实参之前传递给被绑定的方法。
- 注意,一个 绑定函数 也能使用 new 操作符创建对象,这种行为就像把原函数当成构造器,thisArg 参数无效。也就是 new 操作符修改 this 指向的优先级更高。
1 | Function.prototype.myBind = function (thisArg) { |
案例
1 | function Person(name) { |
1 | var animal = { |
我想让 person.showName()运行后 name 变成 yyy,该如何操作?
1 | person.showName.call(animal); |
他们改变了 this 的指向。
具体分析二(call、apply 的区别:接受参数的方式不一样。)
1 | var arr = [1, 5, 9, 3, 5, 7]; |
apply 的第二个参数必须是一个包含多个参数的数组(或类数组对象)
- Post link: https://blog.gaocaipeng.com/2020/04/13/xhncpz/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.