一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
本题难度:⭐ ⭐
执行下面的代码, 打印出来的值是什么?
全部答对,this 就掌握了。
牢记阿林总结的知识点:
-
全局上下文的 this 指向 window。
-
函数上下文的 this 指向不是固定不变的,取决于函数处于什么位置、以什么方式调用,可以总结成如下图:
优先级是new 调用 > call、apply、bind 调用 > 对象上的函数调用 > 普通函数调用。
注意:
阿林写这篇文章的目的,不是为了让大家死记硬背,而是为了给出一些思路和实践,让大家更好地理解 this。
一个资深的前端工程师来回答类似这种打印某个值输出什么,也不敢保证一定答对,这很正常。
关键在于,资深前端工程师和入门前端工程师的知识积累和思考方式不同,一个资深的前端工程师,即使忘了 this 指向这个东西,稍微翻一下文档,再动手实践一下,很快就记回来了。
而入门前端工程师如果不懂 this 指向,只知道死记硬背,不去实践的话,很快就会忘记,下次再问还是不会。
第1题
function fn() {
console.log(this) // ?
}
fn()
第2题
'use strict'
function fn() {
console.log(this) // ?
}
fn()
第3题
const obj = {
lastName: 'lin',
fn() {
console.log(this) // ?
console.log(this.lastName) // ?
}
}
obj.fn()
第4题
const obj = {
lastName: 'lin',
fn() {
console.log(this) // ?
console.log(this.lastName) // ?
}
}
const fn = obj.fn
fn()
第5题
const person = {
lastName: 'lin',
wife: {
lastName: 'xxx',
fn () {
console.log(this) // ?
console.log(this.lastName) // ?
}
}
}
person.wife.fn()
第6题
const o1 = {
text: 'o1',
fn () {
return this.text
}
}
const o2 = {
text: 'o2',
fn () {
return o1.fn()
}
}
const o3 = {
text: 'o3',
fn () {
var fn = o1.fn
return fn()
}
}
console.log(o1.fn()) // ?
console.log(o2.fn()) // ?
console.log(o3.fn()) // ?
第7题
const o1 = {
text: 'o1',
fn () {
return this.text
}
}
const o2 = {
text: 'o2',
fn: o1.fn
}
console.log(o1.fn()) // ?
console.log(o2.fn()) // ?
第8题
const foo = {
name: 'lin',
sayName() {
console.log(this.name)
}
}
const bar = {
name: 'xxx'
}
foo.sayName.call(bar) // ?
foo.sayName.apply(bar) // ?
foo.sayName.bind(bar)() // ?
第9题
function Person1 (name) {
this.name = name
}
function Person2 (name) {
this.name = name
return {}
}
function Person3 (name) {
this.name = name
return {
name: 'xxx'
}
}
function Person4 (name) {
this.name = name
return 1
}
const p1 = new Person1('lin')
const p2 = new Person2('lin')
const p3 = new Person3('lin')
const p4 = new Person4('lin')
console.log(p1.name) // ?
console.log(p2.name) // ?
console.log(p3.name) // ?
console.log(p4.name) // ?
第10题
var lastName = 'xxx'
const obj1 = {
lastName: 'lin',
fn() {
setTimeout(function() {
console.log(this.lastName) // ?
})
}
}
const obj2 = {
lastName: 'lin',
fn() {
setTimeout(() => {
console.log(this.lastName) // ?
})
}
}
obj1.fn()
obj2.fn()
第11题
var lastName = 'xxx'
const obj1 = {
lastName: 'lin',
fn() {
return () => {
console.log(this.lastName) // ?
}
}
}
const obj2 = {
lastName: 'lin',
fn() {
return () => {
return () => {
console.log(this.lastName) // ?
}
}
}
}
obj1.fn()()
obj2.fn()()()
第12题
function foo() {
return a => {
console.log(this.a)
}
}
const obj1 = {
a: 2
}
const obj2 = {
a: 3
}
const bar = foo.call(obj1) // ?
bar.call(obj2) // ?
第 13 题
var a = 100
const foo = () => () => {
console.log(this.a)
}
const obj1 = {
a: 2
}
const obj2 = {
a: 3
}
const bar = foo.call(obj1) // ?
bar.call(obj2) // ?
第 14 题
let a = 100
const foo = () => () => {
console.log(this.a)
}
const obj1 = {
a: 2
}
const obj2 = {
a: 3
}
const bar = foo.call(obj1) // ?
bar.call(obj2) // ?
答案
// 第1题
window
// 第2题
undefined
// 第3题
{lastName: 'lin', fn: ƒ}
'lin'
// 第4题
window
undefined
// 第5题
{lastName: 'xxx', fn: ƒ}
'xxx'
// 第6题
'o1'
'o1'
undefined
// 第7题
'o1'
'o2'
// 第8题
'xxx'
'xxx'
'xxx'
// 第9题
'lin'
undefined
'xxx'
'lin'
// 第10题
'xxx'
'lin'
// 第11题
'lin'
'lin'
// 第12题 箭头函数的绑定无法被修改
2
bar.call(obj2) 啥也不输出
// 第13题 原理同12题
100
bar.call(obj2) 啥也不输出
// 第14题 let 声明的变量不会挂载到 window 上
undefined
bar.call(obj2) 啥也不输出
结尾
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
上一篇:
下一篇: