惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
爱范儿
爱范儿
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
宝玉的分享
宝玉的分享
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
Recent Announcements
Recent Announcements
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
D
Docker
博客园 - Franky
有赞技术团队
有赞技术团队
G
Google Developers Blog

博客园 - 前端架构师

DSH 插件第二弹生态全景:11 个插件,把 DeepSeek 变成一个完整的 Coding Agent 平台 DSH 插件推荐清单:DeepSeek Harness 必装的 14 个插件 手摸手教你做一个codex桌面宠物 告别信息碎片化!我把 Claude Code、Cursor、MCP 和 Vibe Coding 整理成了一座全能 AI 宝库(建议收藏) Claude Code 源码架构分析 我不是狐狸,我是那Harness Engineering 小龙虾的自我养成之路 vue3+ts添加公共富文本组件 vue watch详解 微信授权没搞过? css3图片防止变形 公众号使用微信sdk的正确姿势 web离线应用前提之离线检测 es6手写一个call 同学给我来个手写的new吧 this绑定番外篇之箭头函数绑定 vue中引入公用过滤器? this详解下 012天this详解上 011天之跨域资源共享CORS 010天JSON.stringify()详解 009天之跨浏览器的事件处理程序 使用XHR上传文件要不要了解一下?
this综合篇
前端架构师 · 2020-03-22 · via 博客园 - 前端架构师
var name = 'window'
var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = { name: 'person2' }

person1.foo1() 
person1.foo1.call(person2) 

person1.foo2() 
person1.foo2.call(person2) 

person1.foo3()() 
person1.foo3.call(person2)() 
person1.foo3().call(person2) 

person1.foo4()() 
person1.foo4.call(person2)() 
person1.foo4().call(person2)




答案:
// 'person1'
// 'person2'


// 'window'
// 'window'

// 'window'
// 'window'
// 'person2'



// 'person1'
// 'person2'
 // 'person1'

var name = 'window'
function Person (name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  },
  this.foo2 = () => console.log(this.name),
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  },
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.foo1() 
person1.foo1.call(person2) 

person1.foo2() 
person1.foo2.call(person2) 

person1.foo3()() 
person1.foo3.call(person2)() 
person1.foo3().call(person2) 

person1.foo4()() 
person1.foo4.call(person2)() 
person1.foo4().call(person2) 


答案:
// 'person1'
// 'person2'

// 'person1'
// 'person1'

// 'window'
// 'window'
// 'person2'


// 'person1'
// 'person2'
// 'person1'
var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)

person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)


答案是:


window
window
person2


obj
person2
obj

person1.obj.foo1()()返回的是一个普通的匿名函数,调用它的是window,所以打印出window。
person1.obj.foo1.call(person2)()中是使用.call(person2)改变第一层函数中的this,匿名函数和它没关系,依旧是window调用的,所以打印出window。
person1.obj.foo1().call(person2)是通过.call(person2)改变匿名函数内的this,所以绑定有效,因此打印出person2。
person1.obj.foo2()()第一层为普通函数,第二层为匿名箭头函数。首先让我们明确匿名箭头函数内的this是由第一层普通函数决定的,所以我们只要知道第一层函数内的this是谁就可以了。而这里,第一层函数最后是由谁调用的呢 🤔️?是由obj这个对象,所以打印出obj。
person1.obj.foo2.call(person2)()中使用.call(person2)改变了第一层函数中的this指向,所以第二层的箭头函数会打印出person2。
person1.obj.foo2().call(person2)中使用.call(person2)想要改变内层箭头函数的this指向,但是失败了,所以还是为外层作用域里的this,打印出obj。





function foo() {
  console.log( this.a );
}
var a = 2;
(function(){
  "use strict";
  foo();
})();


答案并不是undefined,也不会报错,而是打印出了2。
其实这里是有一个迷惑点的,那就是"use strict"。
我们知道,使用了"use strict"开启严格模式会使得"use strict"以下代码的this为undefined,也就是这里的立即执行函数中的this是undefined。
但是调用foo()函数的依然是window,所以foo()中的this依旧是window,所以会打印出2。
如果你是使用this.foo()调用的话,就会报错了,因为现在立即执行函数中的this是undefined。
或者将"use strict"放到foo()函数里面,也会报错。


这几个题前面this详解的时候有详细描述,不懂的可以翻阅之前this的内容。也可留言。

欢迎加群一起进步