-
Notifications
You must be signed in to change notification settings - Fork 892
Open
Description
var foo = {
bar: function(){
return this.baz;
},
baz:1
}
console.log(typeof (f=foo.bar)());
//写出执行结果,并解释原因
每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案
欢迎大家在下方发表自己的优质见解
二维码加载失败可点击 小程序二维码
Activity
[-]Day12:写出执行结果,并解释原因[/-][+]Day12:写出执行结果,并解释原因[/+]Genzhen commentedon Jun 22, 2020
答案
undefined
userkang commentedon Jan 15, 2021
这里并不是因为赋值给 f ,相当于f(),所以this指向window的。
不然试试下面代码也会打印 undefined
下面简单从规范的角度判断这个this指向,可以分以下几个步骤:
1.计算 MemberExpression 的结果赋值给 ref
2.判断 ref 是不是一个 Reference 类型
userkang commentedon Jan 15, 2021
解释下这两个步骤:
1、MemberExpression 我们可以简单理解为括号前的部分,针对这题就是
(f=foo.bar)
这部分。2、Reference 是规范类型的一种。如果通过 GetValue 方法从 Reference 类型中获取值,则该 MemberExpression 返回结果不再是 Reference 类型。
这里的关键就是判断 MemberExpression 的返回结果是不是 Reference 类型。
由于
f=foo.bar
存在赋值操作符,根据规范 11.13.1 Simple Assignment ( = ) 规定,其第三步使用了 GetValue(ref),故返回值不是 Reference 类型。对照上述 2.3 的规范,如果表达式返回值不是 Reference 类型,那么 this 的值为 undefined,在非严格模式下,被隐式转换为全局对象 window。
Genzhen commentedon Jan 15, 2021
感谢提出指正Thanks♪(・ω・)ノ
mrluos commentedon Apr 28, 2021
从 《你不知道的JavaScript 上卷》中有这么一个例子
function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; o.foo(); // 3 (p.foo = o.foo)(); // 2
`
书里是这样说的:赋值表达式 p.foo = o.foo 的返回值是目标函数的引用,因此调用位置是 foo() 而不是
p.foo() 或者 o.foo()。根据我们之前说过的,这里会应用默认绑定
mrluos commentedon Apr 28, 2021
个人想法:
这里的意思是返回的不是p.foo然后()调用,而是o.foo的引用然后直接()调用相当于是在全局下调用了,
var foo = { bar: function(){ return this.baz; }, baz:1 } var baz=3; console.log(typeof (foo.bar=foo.bar)()); 输出number
不知道我这样理解对不对?
Chorer commentedon Sep 14, 2021
我也觉得这样更容易理解。从规范的角度去理解可能也行,但这不就是间接说明如果没有阅读过规范,这道题就做不出来了吗?难不成每个人都要阅读规范。。?
SnailOwO commentedon Nov 17, 2021
这是属于this隐式丢失三项中的,函数别名。
this隐式丢失有三种:函数别名、回调传参、将函数值传给语言内置函数(setTimeout第一个参数等等等)