通过面试题来说明this的使用
文章目录
循序渐进,从调用函数到this本质。本次实验在浏览器基础上可以实现,直接使用node是不能实现部分内容的(原因是浏览器自动转化的全局对象)
直接调用函数
function get(content){
console.log(content)
}
get('hello')
// 上述的用法,相当于下面这行代码的语法糖
get.call(window,'hello')
直接调用对象方法
let name ="Window"
let person ={
name:"person",
get:function(){
console.log(this.name)
}
}
person.get() // outs: person
// 同理,上述用法为下面代码的语法糖
person.get.call(person) // outs: person
person.get.call(window) // outs: Window
箭头函数的this
- 箭头函数的this是定义函数时绑定的,而不是执行函数时
- 箭头函数中this是固定的,本身没有this,内部的this就是外层代码块的this(即继承自父元素的执行上下文)
- 也是这个原因,箭头函数不能作为构造函数
let x = 111
let obj = {
x:222,
say:()=>{
console.log(this.x)
}
}
obj.say() /// 111
// 因为 定义箭头函数时,父元素的执行上下文为window对象,所以this.x 为111
如何指定对象内部的x呢?
let x= 111
let obj ={
x:222,
say:()=>{
let fn = ()=> console.log(this.x)
fn()
}
}
obj.say() // 222
面试题
看一道面试题,巩固一下之前的知识
var name = 222
let objA = {
name:111,
say:function(){
console.log(this.name)
}
}
let objB = {
name:333,
say:function(fun){
fun()
}
}
let fun = a.say
fun()
objA.say()
objB.say(objA.say)
objB.say = objA.say
objB.say()
题解
var name = 222 // let 声明的不在window对象上(html中处于script 域中)
let objA = { // 不能通过作用域链找到,但是可以objA来进行使用,上面同
name:111,
say:function(){
console.log(this.name)
}
}
let objB = {
name:333,
say:function(fun){
fun()
}
}
let fun = objA.say
fun() // => 222 等效于 fun.call(window) 运行时绑定当前this(window)
objA.say() // 111 等效于 objA.say.call(objA)
objB.say(objA.say) // 222 等效于 objB.say.call(objB,objA.say).call(window)
// 函数运行时绑定执行上下文,运行内部的fun() 时候,上下文为window对象
objB.say = objA.say
objB.say() // 333 等效于 objB.say.call(objB) (objA.say.call(objB))