好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 thinkyou 于 2022-1-13 14:20 编辑
[JavaScript] 纯文本查看 复制代码 function foo() {
console.log(this.a)
}
var a = 1
foo()
const obj = {
a: 2,
foo: foo
}
obj.foo()
const c = new foo()
1.对于直接调foo来说,不管foo函数被放在了什么地方,this一定是window
2.对于obj.foo()来说,我们只需要记住,谁调用了函数,谁就是this ,所以在这个场景下foo函数中的 this 就是obj 对象
3.对于new 的方式来说,this被永远绑定在了c上面,不会被任何方式改变this
我们再来看看箭头函数的this
[JavaScript] 纯文本查看 复制代码 function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
1.首先箭头函数其实是没有this 的,箭头函数中的this 只取决包裹箭头函数的第一个
普通函数的this 。在这个例子中,因为包裹箭头函数的第一个普通函数是a ,所以此
时的this 是window 。另外对箭头函数使用bind 这类函数是无效的
2.最后种情况也就是bind 这些改变上下文的API 了,对于这些函数来说, this 取决
于第一个参数,如果第一个参数为空,那么就是 window 。
3.那么说到bind ,不知道大家是否考虑过,如果对一个函数进行多次bind ,那么上下文
会是什么呢?
[Asm] 纯文本查看 复制代码 let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)() // => ?
如果你认为输出结果是a ,那么你就错了,其实我们可以把上述代码转换成
另一种形式
[JavaScript] 纯文本查看 复制代码 // fn.bind().bind(a) 等于
let fn2 = function fn1() {
return function() {
return fn.apply()
}.apply(a)
}
fn2()
可以从上述代码中发现,不管我们给函数bind 几次, fn中的this 永
远由第一次bind 决定,所以结果永远是 window
[JavaScript] 纯文本查看 复制代码 let a = { name: 'poetries' }
function foo() {
console.log(this.name)
}
foo.bind(a)() // => 'poetries'
以上就是 this 的规则了,但是可能会发生多个规则同时出现的情况,这时
候不同的规则之间会根据优先级最高的来决定 this 最终指向哪里。
首先, new 的方式优先级最高,接下来是 bind 这些函数,然后是obj.foo() 这种调用方式,最后是 foo 这种调用方式,同时,箭头函数的
this 一旦被绑定,就不会再被任何方式所改变。
总结:
(1)普通函数调用: 函数名() ->this指向window
(2)对象方法调用: 对象名.方法名() ->this指向对象
(3)构造函数调用: new 函数名() ->this指向new创建的实例对象
上下文调用方式:
1.call上下文调
[JavaScript] 纯文本查看 复制代码 function fn(a,b){
console.log( this )
console.log(a+b)
}
fn(1,2)//this指向window
//函数名.call(修改的this,参数1,参数2,....)
fn.call({name:'张三'},10,20)
2.apply上下文调用 //场景1:伪数组转成真数组
[JavaScript] 纯文本查看 复制代码 function fn(a,b){
console.log(this)
console.log(a+b)
}
//函数名.apply(修改的this, 数组/伪数组 )
//apply传参的时候会自动的遍历这个数组,然后按照循序逐一传参 a = [30,40][0] b=[30,40]
fn.apply({name:'李四'},[30,40])
3.bind上下文调用
[JavaScript] 纯文本查看 复制代码 //bind不会立即调用函数,而是得到一个修改this之后的新函数
function fn(a,b){
console.log(this)
console.log(a+b)
}
let newFn = fn.bind({name:'王五'}) //这里如果传实参后,下面传参就无效了
newFn(25,66)
请说说call apply bind的区别及对应应用场景(面试必问点)
共同点:
都可以修改this的指向
call、apply的区别:接受参数的方式不一样。
bind:不立即执行。而apply、call 立即执行。
call逗号分隔逐一传递实参
apply 必须是一个包含多个参数的数组(或类数组对象)
bind不会立即执行,会返回修改this后的一个函数
|
免费评分
-
参与人数 2 | 吾爱币 +8 |
热心值 +2 |
收起
理由
|
无缺i
| + 1 |
+ 1 |
谢谢@Thanks! |
苏紫方璇
| + 7 |
+ 1 |
欢迎分析讨论交流,吾爱破解论坛有你更精彩! |
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|