
代码如下:
var name="Window"; var object={ name:"object", getName:function (){ var a= function(){ return this.name; }; console.log(a()); return a; } } object.getName()(); 运行结果:
Window Window 我的问题在于console.log(a());这一行。return a后,是在全局作用域中执行的返回的匿名函数,所以this的值是window。但是我在getName函数中直接执行a()的话,根据this的定义“ this 指向函数运行时的执行环境对象”,而每个函数执行时都会创建一个自己的执行环境,那么a()执行时this的值应该是getName函数的环境对象,这样 a 函数内对this.name的引用就应该得到undefined。请问我的理解有什么问题呢?谢谢:)
2 4ark 2019 年 1 月 30 日 via Android 就你这段代码而言,a 并不属于任何对象,也没有通过 call 等方法调用,所有这样的函数 this 默认指向 Window,如果是严格默认下,就是 undefinde。 |
3 4ark 2019 年 1 月 30 日 via Android 收回我说的第一句话,才发现我的文章代码也没有格式,为什么 V2EX 会这样?? |
9 Nitroethane 2019 年 1 月 30 日 via Android |
10 4ark 2019 年 1 月 30 日 via Android @Nitroethane 求下载链接,感激不尽! |
11 4ark 2019 年 1 月 30 日 via Android @Nitroethane 已在 play 商店搜到 |
12 rabbbit 2019 年 1 月 30 日 this 是什么取决于如何调用 本文中 a 函数的调用者是 a() 而非外层的 object.getName() 当 a 函数被作为变量调用时, 会将内部方法 GetBase(ref). ImplicitThisValue 返回的值作为 thisArg(通常是 undefined) http://ecma-international.org/ecma-262/5.1/#sec-11.2.3 在进入函数时 1 如果是严格模式,把 this 指向 thisArg 2 如果 thisArg 为 undefined,则将 this 指向 window http://ecma-international.org/ecma-262/5.1/#sec-10.4.3 总之一句话,作为变量调用的函数里边的 this 都指向 window |
13 OSF2E 2019 年 1 月 30 日 《 Javascript 高级程序设计(第三版)》( P73 ) 4.2 执行环境与作用域 |
14 rabbbit 2019 年 1 月 30 日 |
15 fourstring OP @OSF2E #13 谢谢,我看的就是这本书。我之所以会认为 a()的结果是"object",就是因为这本书 5.5.4 里说 this “引用的是函数执行的环境对象”,然后 4.2 节说“每个函数都有自己的执行环境”,我看了下面别的 v 友回复以后,觉得应该是我对“执行环境”理解有误,但是这本书里确实没有明确讲解函数的执行环境究竟是什么(也就是不是词法环境)。 |
16 fleam 2019 年 1 月 30 日 via Android 我总结的就是相关性就近原则,菜鸟飞过。。。 |
17 X37B 2019 年 1 月 30 日 this(4 个规则):函数位置上的调用形式 默认绑定 独立调用 fn() this -->window "use strict" this --> undefined 隐式绑定 对象.对象.fn() this -->最近的调用者 隐式丢失? 使用隐式调用的形式进行传参 赋值;使用其他形式进行调用 this 的指向发生改变 解决隐式丢失? 硬绑定 bind 返回一个新的函数 显示绑定 apply call 立即调用 this --> 绑定的对象 构造绑定 new fn() this --> 构造出来的实例对象 当一行代码出现多个绑定,this 绑定优先级:new --> 显示 --> 隐式 --> 默认 |
18 shintendo 2019 年 1 月 30 日 其实很简单,你的 this 在哪个函数里面?在 a 里面,那么 this 的值只取决于 a 被谁调用,跟其它什么 getName 没有任何关系。 而所谓的 a 被谁调用,指的是“调用者.a()”这种调用,不是说 a()写在 getName 里面就是被 getName 调用了这种意思。 |
19 fourstring OP @X37B #17 请问知道这样的知识什么地方或者书能看到呢 |
20 secondwtq 2019 年 1 月 30 日 @fourstring 犀牛书应该是这样理解语言设计者的意图的:词法作用域和 this 都属于函数运行环境 /上下文,现在的实践中,一般词法作用域是写代码时固定的,this 允许用户在运行时动态指定上下文,并且这东西和函数调用语法关联,因此也是一种“环境” 实际上现在的 OO 语言对于 this 的实现基本就是函数参数,也就是非要说的话所有参数都是“环境”的一部分 ... 不过 OO 的语义上 this 确实有环境的意思 词法作用域环境也可以动态绑定,用 eval 或者 with 就行,只不过现在没人用了 |
21 OSF2E 2019 年 1 月 30 日 @fourstring 首先,这部分内容要结合第 7 章的内容来理解。 另外,这一节有一个关键概念是执行环境的变量对象( variable object ),每一个函数的执行环境( execution context )中所定义的变量和函数都保存在这个对象中。而 web 浏览器中最外层的执行环境(的变量对象)被认为是 window 对象,因此所有全局变量和函数都是作为 window 对象的属性和方法创建的。 因此,你的代码中的匿名函数 a 在定义之初便自动“挂靠”到全局执行环境中的(解析器就是这么解析的,没有为什么),即该匿名函数是 window 对象的方法,所以 this 自然指向 window。 可以使用 bind 方法改变该匿名函数“挂靠”的变量对象,代码如下: var a = function(){}.bind(this); |
23 rabbbit 2019 年 1 月 30 日 如果指的是第 7 章 182 页 "匿名函数的执行环境具有全局性" 这句话的话 这句话是翻译错误,原文是 ``` Anonymous functions are not bound to an object in this context, meaning the this object points to window unless executing in strict mode (where this is undefined). ``` 翻译:在这个上下文(执行环境)中匿名函数并没有绑定到任何一个对象中,意味着 this 指向 window (除非这个上下文(执行环境)是在严格模式下执行的,而严格模式下该 this 指向 undefined ) https://www.zhihu.com/question/21958425/answer/278063919 |
24 palmers 2019 年 1 月 30 日 this 是动态的指向当前对象 并不会主动的缓存 所以 是 window 在 getName 函数中将 this 缓存起来就会得到你预料的结果了 |
25 autoxbc 2019 年 1 月 30 日 个人觉得我的理解最接近本质 记住唯一一条规则:this 是隐参数,在成员访问过程中,如果属性是函数,且不是箭头函数,宿主作为隐参数传递给属性 这里的关键是成员访问,这是个在宿主对象上查找属性的过程,语句反应了这个过程,隐参数就会传递 --------------------- console.log( a() ) 这里 a 是函数,但是查找 a 的过程不是成员访问,所以没有隐参数 --------------------- 既然 this 是隐参数,bind call apply 就是隐参数显式传递,这个是不是非常自然 |
26 OSF2E 2019 年 1 月 31 日 |
27 mamahaha 2019 年 1 月 31 日 这种问题你今天想明白了也许第二天又糊涂了,所以没必要浪费时间钻研,把它看成黑箱就得了 |
28 yxcoder 2019 年 1 月 31 日 举个栗子: let obj = { getThis(){ console.log(this); let func = function(){ console.log(this); } func(); } } obj.getThis(); 两个 console 分别会输出什么? |
30 X37B 2019 年 1 月 31 日 |
31 libook 2019 年 1 月 31 日
|