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

推荐订阅源

WordPress大学
WordPress大学
N
News | PayPal Newsroom
雷峰网
雷峰网
Y
Y Combinator Blog
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
Blog — PlanetScale
Blog — PlanetScale
F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
The Cloudflare Blog
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
Vercel News
Vercel News
N
Netflix TechBlog - Medium
GbyAI
GbyAI
博客园 - 司徒正美
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
J
Java Code Geeks
P
Proofpoint News Feed
I
InfoQ
IT之家
IT之家
F
Full Disclosure
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
Forbes - Security
Forbes - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
The Last Watchdog
The Last Watchdog
月光博客
月光博客
W
WeLiveSecurity
S
Securelist
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
T
Threat Research - Cisco Blogs
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - Franky
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

博客园 - 前端架构师

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的内容。也可留言。

欢迎加群一起进步