写出控制台打印结果
Q1
var User = {
count: 1,
action: {
getCount: function () {
return this.count
}
}
}
var getCount = User.action.getCount
setTimeout(() => {
console.log('result 1', User.action.getCount())
})
console.log('result 2', getCount())
解析
// 输出结果:
// result 2 undefined
// rensult 1 undefined
- 对象中的属性的值如果不是原始类型(是对象),存储的是指向这个对象的指针(内存地址)
- 所以 var getCount 被赋值后,拷贝的是 同名方法的内存地址
- 打印 result 2 时 getCount 被调用,调用者是全局,浏览器环境就是 window.getCount()
- 非箭头函数调用时,内部的this指向这个函数的调用者
- 简单的讲就是
.
前面的对象,所以两个位置调用getCount 时内部this的指向:- User.action.getCount()指向 User.action
- getCount() 指向 全局(浏览器环境:window)
- 简单的讲就是
- setTimeout 会创建异步任务,即将回调函数放到队列中(而不是在本次执行任务中),在本次代码全部执行完(同步执行的代码部分),才会轮到队列中的任务执行。
- 所以 result1 在 result2 后面被打印出来
Q2
在只考虑浏览器环境下,控制台打印结果:
var length = 10
function fn() {
console.log(this.length)
}
var obj = {
length: 5,
method: function (fn) {
fn()
arguments[0]()
}
}
obj.method(fn, 1)
解析
输出结果:
// 10
// 2
非箭头函数调用时,内部的this指向这个函数的调用者.
首先method被obj调用,所以method执行时内部this指向obj,然而method内部并没有用到this。
fn被直接调用,相当于被全局调用。浏览器环境就是window对象。所以此时fn内部的this指向window
浏览器环境中,在全局声明的变量,window都可以访问到。
所以this.length打印的是全局变量length。
主要陷阱是arguments[0]()
。
错误理解是先解析 arguments[0]
,获取到 fn
方法,最终类似前面的fn()
。
可实际上,这里相当于:arguments 调用了下标为0的元素指向的方法fn。所以fn中this指向arguments,即arguments.length,结果为2。
所以通过下标获取对象的方法属性并调用时,方法内部this的指向,同使用obj.key
方法一样。
var arr = [
function () {
console.log(this.length)
},
2, 3, 4
]
arr[0]() // 4
var obj = {
length: 10,
fn: function () {
console.log(this.length)
}
}
obj['fn']() // 10
Q3
console.log(typeof (() => {})) // function
console.log(typeof ['数组', '结果']) // object
console.log(typeof null) // object
console.log(typeof undefined) // undefined
console.log(typeof Function.prototype) // function
console.log('张三' instanceof String) // false
console.log(new Date() instanceof Date) // true
Q4
var User = {
count:1,
action:{
getCount:function () {
return this.count
}
}
}
var getCount = User.action.getCount;
setTimeout(() => {
console.log("result 1",User.action.getCount())
})
console.log("result 2",getCount())
回答:
result 2 undefined
result 1 undefined
setTimeout 的回调是在宏任务中,当当前执行栈中的任务执行完毕才会执行。
result2 的 getCount 是全局调用,浏览器环境中相当于 window.getCount(),this指向window,所以return undefined。
result1 的 getCount 中的 this 指向方法的调用者 User.action,这个对象下只有getCount一个成员,所以 User.action.count 返回 undefined