关于let声明的变量在window里无法获取到的问题
之所以说到这个问题是因为,我在面试过程中,遇到一个面试题,就是this指向的问题,当时面试官并没有说答案是什么,我回来后经过试验,发现我的答案是错的,以下是面试题:
let len = 10;
function fn() {
console.info(this.len)
}
fn();
let Person = {
len: 5,
say: function() {
fn();
arguments[0]();
}
}
Person.say(fn);
乍一看,很简单嘛,第一个fn()里this指向window撒。但是你自己执行一遍就会发现fn()输出的是’undefined’。
为什么会出现这种问题,就需要知道ES6与ES5变量声明方面的区别了:
- ES5声明变量只有两种方式:var和function。
- ES6有let、const、import、class再加上ES5的var、function共有六种声明变量的方式。
- 还需要了解顶层对象:浏览器环境中顶层对象是window,Node中是global对象。
- ES5中,顶层对象的属性等价于全局变量。(敲黑板了啊)
- ES6中,有所改变:var、function声明的全局变量,依然是顶层对象的属性;let、const、class声明的全局变量不属于顶层对象的属性,也就是说ES6开始,全局变量和顶层对象的属性开始分离、脱钩。
所以ES6非严格模式下,与var声明的全局变量都会成为window的属性:
a = 1;
console.info(window.a); // 1
var b = 2;
console.info(window.b); // 2
而使用let声明的全局变量,不会成为window的属性:
let c = 3;
console.info(window.c); // undefined
至于
arguments[0](); // undefined
是因为arguments对象调用fn方法,此时arguments对象里没有len属性,所以会报undefined,若是这样写,就会打印出不同的结果:
let len = 10;
function fn() {
console.info(this.len)
}
fn(); // undefined
let Person = {
len: 5,
say: function() {
fn(); // undefined
arguments.len = 20;
arguments[0](); // 20
}
}
Person.say(fn);
网上我还看到了其他的坑:
var length = 10;
function fn() {
console.info(this.length)
}
fn(); // 10
let Person = {
len: 5,
say: function() {
fn(); // 10
arguments[0](); // 1
}
}
Person.say(fn);
执行arguments[0]方法之所以输出1,是因为它的length属性啊,关于函数的length属性。。。
呃,写的有点多了,再写一篇解释函数的length属性。