FE-Interview
FE-Interview copied to clipboard
Day12:写出执行结果,并解释原因
var foo = {
bar: function(){
return this.baz;
},
baz:1
}
console.log(typeof (f=foo.bar)());
//写出执行结果,并解释原因
每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案 欢迎大家在下方发表自己的优质见解 二维码加载失败可点击 小程序二维码
扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

答案 undefined
这里并不是因为赋值给 f ,相当于f(),所以this指向window的。 不然试试下面代码也会打印 undefined
var foo = {
bar: function(){
return this.baz;
},
baz:1
}
console.log(typeof (foo.bar=foo.bar)());
下面简单从规范的角度判断这个this指向,可以分以下几个步骤:
1.计算 MemberExpression 的结果赋值给 ref
2.判断 ref 是不是一个 Reference 类型
2.1 如果 ref 是 Reference,并且 IsPropertyReference(ref) 是 true, 那么 this 的值为 GetBase(ref)
2.2 如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref)
2.3 如果 ref 不是 Reference,那么 this 的值为 undefined
解释下这两个步骤:
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。
这里并不是因为赋值给 f ,相当于f(),所以this指向window的。 不然试试下面代码也会打印 undefined
var foo = { bar: function(){ return this.baz; }, baz:1 } console.log(typeof (foo.bar=foo.bar)());
下面简单从规范的角度判断这个this指向,可以分以下几个步骤:
1.计算 MemberExpression 的结果赋值给 ref
2.判断 ref 是不是一个 Reference 类型
2.1 如果 ref 是 Reference,并且 IsPropertyReference(ref) 是 true, 那么 this 的值为 GetBase(ref) 2.2 如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref) 2.3 如果 ref 不是 Reference,那么 this 的值为 undefined
感谢提出指正Thanks♪(・ω・)ノ
解释下这两个步骤: 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。
从 《你不知道的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()。根据我们之前说过的,这里会应用默认绑定
解释下这两个步骤: 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。从 《你不知道的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()。根据我们之前说过的,这里会应用默认绑定
个人想法:
这里的意思是返回的不是p.foo然后()调用,而是o.foo的引用然后直接()调用相当于是在全局下调用了,
var foo = { bar: function(){ return this.baz; }, baz:1 } var baz=3; console.log(typeof (foo.bar=foo.bar)()); 输出number
不知道我这样理解对不对?
解释下这两个步骤: 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。从 《你不知道的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()。根据我们之前说过的,这里会应用默认绑定个人想法: 这里的意思是返回的不是p.foo然后()调用,而是o.foo的引用然后直接()调用相当于是在全局下调用了,
var foo = { bar: function(){ return this.baz; }, baz:1 } var baz=3; console.log(typeof (foo.bar=foo.bar)()); 输出number
不知道我这样理解对不对?
我也觉得这样更容易理解。从规范的角度去理解可能也行,但这不就是间接说明如果没有阅读过规范,这道题就做不出来了吗?难不成每个人都要阅读规范。。?
这是属于this隐式丢失三项中的,函数别名。 this隐式丢失有三种:函数别名、回调传参、将函数值传给语言内置函数(setTimeout第一个参数等等等)