求教一个问题.

2017-08-03 20:19:39 +08:00
 xrr2016

今天我在 javascript 高级程序设计第 7 章 上看到这样一段代码

var name = 'window'
var obj = {
  name: 'obj',
  getName: function () {
    return this.name
  }
}

obj.getName() // 输出 'obj'
(obj.getName)() // 输出 'obj')
(obj.getName = obj.getName)()  // 输出 'window'

我理解为

(obj.getName = obj.getName)() 
// 等同于
(function() { return this.name })()

不知这样想是否正确?

然后我又用 let 和 const 试了一下, 结果都输出空字符串, 说以想问下原因何在?

2235 次点击
所在节点    程序员
14 条回复
suikator
2017-08-03 21:20:08 +08:00
Variable is assigned to itself
This inspection reports any assignments of the form x = x in JavaScript content. These are pointless, and usually indicate programmer error
geelaw
2017-08-03 21:27:27 +08:00
我先提示一下 obj 是 const 的意思是 obj 不能改变引用了哪个对象,并不是对象本身不可改变,在这个例子里 const 不 const 不会有区别
suikator
2017-08-03 21:35:23 +08:00
在 var name = 'window' 下面 console 一下 this 吧 看看里面有没有 name,我估计没有

研究这些操蛋的东西真的有前途吗 - -!
xrr2016
2017-08-03 21:50:43 +08:00
@suikator 肯定有啊,var name = 'window' 的时候 this 就是全局对象.
哈哈. 我也只是今天在看书的时候看到的,也算不上研究吧。
xrr2016
2017-08-03 21:57:27 +08:00
@geelaw 不太能理解您的意思,按理说 `(obj.getName = obj.getName)()` 这句执行的时候,运行的都是 `return this.name` 啊, 为什么 `var` 声明可以输出 'window', 而 `let` 和 `const` 声明不行呢?
suikator
2017-08-03 22:14:19 +08:00
@xrr2016
区分 全局中的 this 函数中的 this 构造函数中的 this 以及 this 的指向
chrome 浏览器环境 全局中的 this === windows
此时 (obj.getName = obj.getName)() 输出 'window' 没毛病
其他环境我不清楚 你自己打印吧 我也不是很熟练 js
fulvaz
2017-08-03 22:30:58 +08:00
楼主的问题好有意思,我测试发现了几个问题

问题 1
----
楼主的第一段代码就跑不通吧?

```
(obj.getName)()
````
会产生 TypeError

问题 2
---
楼主在 console 中分段执行的代码, 如果连在一起执行的话

```
let name = 'window2'
let obj = {
name: 'obj',
getName: function() {
return this.name
}
}
(obj.getName = obj.getName)()
```

Uncaught ReferenceError: obj is not defined


值得研究一番
fulvaz
2017-08-03 22:33:21 +08:00
@fulvaz

分号的问题,分号的问题。。。下次弄明白了再扔上来
xrr2016
2017-08-03 23:10:35 +08:00
@fulvaz 跑的通啊, 你怎么跑不通的...
RLib
2017-08-03 23:28:39 +08:00
@xrr2016 因为 `var` 和 `let const` 的作用域不一样, var 声明的作用域是全局的, 用 this 得到 window, 但是 let 是块级作用域(并且不是全局作用域), let 声明的全局变量也不具有全局对象的属性, 这时候 this.name 就是 undefined
fulvaz
2017-08-04 00:51:06 +08:00
@RLib 我觉得与作用域无关啊

楼主的代码中有个小坑,就是 window.name 是存在的, 值为""

楼主迷惑的话可以尝试下这样的代码

代码 1
----

```
window.name; // -> ""
var name = 123;
window.name; // -> 123
```

var 竟然能修改全局变量的值

代码 2
---
```
window.name; // ""
let name = 123;
window.name; // ""
````

let 不会修改全局变量

-------------------------

总结而言就是...js 的历史遗留问题,var 定义的变量到底保存在哪里。
xrr2016
2017-08-04 09:05:21 +08:00
@fulvaz 这不是历史遗留问题吧, 代码运行的时候本来就有一个全局对象存储变量啊
RLib
2017-08-04 10:30:52 +08:00
@fulvaz 相对来说 let 和 const 是新玩法, var 才是历史产物, 提出 let 就是为了解决`var 任何地方都是全局作用域`而产生的 bug。
window.name 是本来存在, 但因为在 LZ 的代码里并没体现, 所以我说是 undefined, 但这是全局变量, 而声明的是 let, 不等于全局, let 不会影响全局变量尽管它在全局块, 此外, 既然 let 不能修改全局变量, 不也从另一方面表明 let 的变量不在全局作用域里。所以说来说去就是个简单的作用域问题
xrr2016
2017-08-04 12:35:41 +08:00
@RLib 这样说我就明白了, `window.name` 本来就是空字符串,多谢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/380241

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX