博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阮一峰老师微博上的关于js作用域的一道题
阅读量:7118 次
发布时间:2019-06-28

本文共 1974 字,大约阅读时间需要 6 分钟。

在阮一峰老师的微博上看到这样:

javascriptfunction a(x, y) {    y = function(){        x = 2;    };    return function() {        var x = 3;        y();        console.log(x);    }.apply(this, arguments);}a();

问:输出是多少?为什么?

我想到了答案,并且验证正确,小兴奋,在这里写下解题思路:

  • 这道题的迷惑很多
  • return其实没用,代码可以变成
javascriptfunction a(x, y) {    y = function(){        x = 2;    };    (function() {        var x = 3;        y();        console.log(x);    }).apply(this, arguments);}a();
  • 执行a();其实是执行
javascriptfunction() {    var x = 3;    y();    console.log(x);}apply(this, arguments);

其中:1. this是跟作用域(浏览器环境下是window,node环境下是global),因为是在跟作用域下执行的a();。 2. arguments是空,因为a();没有参数。

  • y();没用。因为y定因为函数首先定义了var x = 3;,所以console.log(x)就是3。因为作用域优先级是从内向外由高到低的,所以在这里var x = 3;的优先级是最高的,y();中不管定义的什么,都不会影响到x。所以之前分析了那么多,其实都没用啊!做题时读代码,顺序要从内部到外部(仅限于做题)~

问题:这道题如果将输出改成console.log(this.x),答案会是什么? 我认为是2,可是结果确实undefined,这是为什么呢? 目前我还没搞明白,求解。

javascriptfunction a(x, y) {    y = function(){        x = 2;    };    return function() {        var x = 3;        y();        console.log(this.x);    }.apply(this, arguments);}a();

补充

我弄明白了上面的问题,重点在于:1. 函数y的作用域,2. 函数a中定义的变量

之前我说y();没用,为什么没用?是因为函数y是定义在函数a下的,所以y的作用域链是这样的:

window

a

y

因为函数a是这样定义的:function a(x, y),所以函数a定义了变量x,所以y中的x = 2;赋值给了函数ax参数。并没有赋值给window作用域下的xconsole.log(this.x);this指的是window,所以输出为undefined。

如果将函数a的参数去掉,题目变成:

javascriptfunction a() {    y = function(){        x = 2;    };    return function() {        var x = 3;        y();        console.log(this.x);    }.apply(this, arguments);}a();

这样函数a中就没有x这个变量了,所以函数y中的x = 2;就会赋值给跟作用域下的x,所以console.log(this.x);的输出就会变成2

再将题目改一下,如果将函数y()定义在return 的匿名函数里面,题目变为:

javascriptfunction a(x, y) {    return function() {        y = function(){            x = 2;        };        var x = 3;        y();        console.log(x);    }.apply(this, arguments);}a();

console.log(x)会输出什么? 答案是2,因为此时y的作用域链是这样的:

window

a

匿名函数

y

因为匿名函数中定义了var x = 3;,所以函数y中的x = 2;就会修改匿名函数中的x的值,所以console.log(x)输出变成了3,


弄明白这道题的每一处细节,对理解javascript语言的作用域很有帮助。虽然这道题对编程本身没有什么意义。

转载地址:http://ejbel.baihongyu.com/

你可能感兴趣的文章
chmod和permission
查看>>
组策略应用之二:重定向文件夹
查看>>
Linux下建立静态库的实例讲解
查看>>
mac显示隐藏文件
查看>>
4-2 ADO.NET-查询和检索数据7
查看>>
远程桌面不能复制粘贴解决办法
查看>>
SQL Server DATEDIFF() 函数 用法
查看>>
深度学习笔记之关于常用模型或者方法
查看>>
使用jenkins配置.net mvc网站进行持续集成三
查看>>
关于增强for循环
查看>>
GENIA项目-综述论文(E99)
查看>>
JavaScript 资源列表
查看>>
SharePoint online Multilingual support - Settings
查看>>
MySQL 传统复制中常见故障处理和结构优化案例分析
查看>>
SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第2部分)
查看>>
简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)...
查看>>
ashx的学习
查看>>
利用LruCache和DiskLruCache加载网络图片实现图片瀑布流效果(升级版)
查看>>
[20170114]12c varchar2类型直方图.txt
查看>>
MySQL---数据库从入门走向大神系列(八)-在java中执行MySQL的存储过程
查看>>