携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
第一题
我们先把代码写一下,var改成了let,这里都是在全局作用域中,无影响
let a = []
a[0] = 1
a[1] = 2
a[2] = 3
a[5] = 4
console.log(a.length);
我们可以看到a.length=6
- 由此我们可知如果直接给一个数组的较后的元素赋值而不给前面的元素赋值,那么数组的长度,会计算最后一个有值的元素之前的所有元素作为长度
- 为了进一步理解,我做一个小例子
let a = []
a[100] = 9
- 然后我们看一下数组a的长度,长度为101.符合我们的预期和理解
- 那么我又产生了第二个疑问:前面为未赋值的元素是啥?
- 我们看到前面未赋值的元素为undefined
- 这是因为一开始声明了a=[]成为了空数组,里面的元素相当于,声明未赋值,所以是undefined
- 我们进一步看看 一个空数组,
- 他的length为多少?
- 如果length为零,那我强行让他告诉我下标为100的元素是啥,他会告诉我们什么呢?
控制台键入代码输出如下
-
首先a[]整个数组为undefined,符合声明未赋值为undefined
-
a.length为0
-
a[100]也为undefined,这说明undefined元素不计入数组的长度,
-
除非最后一个元素有值,则前面undefined的元素计入长度,如第二张图所示
第二题
我们先把代码写一下,var改成了let,这里都是在全局作用域中,无影响
let f = function g() {
return 23
}
- 我们发现键入f,输出的是f函数
- 键入g,输出的是报错g没有被定义
- typeof f() 输出的是'number'
- typeof g()输出的是报错g没有被定义
- f()输出的是23
- g()输出的是报错g没有被定义
原因:
- 我们typeof g ,发现是undefined
- 在JS里,声明函数只有2种方法:
- 第1种:function foo(){...}(函数声明)
- 第2种:var foo=function(){...}(等号后面必须是匿名函数,这句实质是函数表达式)
- 除此之外,类似于var foo=function bar(){..)这样的东西统一按2方法处理,
- 即在函数外部无法通过bar访问到函数,这时候bar不是一个函数,而是作为foo函数的name属性名的属性值,
- 即foo.name='bar'
具体到本题中就是f.name='g';如下图所示:
- 所以g是f函数的name属性的属性值,不是变量名更不是函数
- 所以 typeof g()会报错