话不多说先看题
const name ='a'
const obj={
name:'b',
getName(){
return this.name;
},
prop:{
name:'c',
getName:()=>{
return this.name
}
}
}
console.log(obj.getName())
console.log(obj.getName.call(obj.prop))
console.log(obj.prop.getName())
this 是很多⼈会混淆的概念,但是其实他⼀点都不难,你只需要记住⼏个规则就可以了。
- 第一种情况是this只依赖于调⽤函数前的对象,前面无对象就依赖全局window对象
- 第二种情况是利⽤ call,apply,bind 改变 this。
- 第三种情况是箭头函数 中的 this。 箭头函数其实是没有 this 的,这个函数中的 this 只取决于他外⾯的第⼀个不是箭头函数 的函数的 this 。 所以现在知道答案了吧,答案在文章底部。
call、apply、bind是如何改变this的
- call、apply、bind三个方法都有两个参数;第一个参数都是this(对象),即被改变后的this指向。
- call和apply都是立即执行函数,不必调用。call第二个参数不用数组接收,apply用数组接收,类型可以是任意类型
- bind返回值是一个函数(不会立即执行,需要调用),传参和call一样
- 一个函数.call() 2次或者2次以上 执行的永远是第一个参数(第一个参数需要是一个函数),参数会直接输出
下面来做一些题看看自己有没有真的理解吧。
function a(b){
console.log('执行了a' + this.b1 + b)
}
let b={b1:"b1"};
a.call(b,"第二个参数");
function a(){ console.log(this + '执行了a')};
function b(){console.log(this + "执行了b")}
a.call(b)
a.call.call(b)
我们都知道js的数组处理方法很多,可以很方便的对数据进行增删改截取添加的处理,
所以我们可以利用call将传入具有length属性的参数转为数组.
例如:
let str = 'string'
Array.prototype.slice.call(str, 2)
使用call冒充一个据有length对象,转换成数组,绑定this指向——>对象.slice() 或者 字符.slice() 或者 数组.slice() ——>第二个参数为截取的起始下标
答案是:b c undefined
补充一个知识点: let和const声明的变量不在window上。 ES6规定var命令与function命令声明的全局变量,依旧是顶层对象的属性,但let命令,const命令、 class命令声明的全局变量,不属于顶层的属性。不用对象去取用,在块级作用域中即可取用.