GithubHelp home page GithubHelp logo

Comments (8)

userkang avatar userkang commented on May 1, 2024 2

解释下这两个步骤:
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。

from fe-interview.

Genzhen avatar Genzhen commented on May 1, 2024

答案
undefined

from fe-interview.

userkang avatar userkang commented on May 1, 2024

这里并不是因为赋值给 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

from fe-interview.

Genzhen avatar Genzhen commented on May 1, 2024

这里并不是因为赋值给 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♪(・ω・)ノ

from fe-interview.

mrluos avatar mrluos commented on May 1, 2024

解释下这两个步骤:
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()。根据我们之前说过的,这里会应用默认绑定

from fe-interview.

mrluos avatar mrluos commented on May 1, 2024

解释下这两个步骤:
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
不知道我这样理解对不对?

from fe-interview.

Chorer avatar Chorer commented on May 1, 2024

解释下这两个步骤:
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
不知道我这样理解对不对?

我也觉得这样更容易理解。从规范的角度去理解可能也行,但这不就是间接说明如果没有阅读过规范,这道题就做不出来了吗?难不成每个人都要阅读规范。。?

from fe-interview.

SnailOwO avatar SnailOwO commented on May 1, 2024

这是属于this隐式丢失三项中的,函数别名。
this隐式丢失有三种:函数别名、回调传参、将函数值传给语言内置函数(setTimeout第一个参数等等等)

from fe-interview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.