Javascript学习笔记——数组,函数,作用域,预解析
目录
数组
数组的声明
var arr = [1, 2, 3];
var arr1 = new Array();
var arr2 = new Array(2); // 数组长度,空位补undefined
var arr3 = new Array(2, 3); // 等价于[2, 3]
数组的访问
用下标访问数组元素越界时会得到undefined。
获取数组长度:arr.length
新增数数组元素
- length属性是可读写的,直接修改length的值。扩容之后,新增的位置是undefined。
- 直接使用下标赋值,长度自动更新。空位置自动补undefined。
push(x)
常用方法
方法名 | 说明 | 返回值 |
---|---|---|
push(参数1...) | 未尾添加一个或多个元素,注意修改原数组 | 返回新的长度 |
pop() | 删除数组最后一个元素,把数组长度减1。无参数、修改原数组组 | 返回它删除的元素的值 |
unshift(参数1...) | 向数组的开头添加一个或多个元素,注意修改原数组 | 返回新的长度 |
shift() | 删除数组的第一个元素,数组长度减1。无参数、修改原数组 | 返回第一个元素的值 |
函数
函数的两种声明方式
利用函数关键字自定义函数(命名函数)
function fn() {
console.log('我是函数');
}
函数表达式(匿名函数)
var fun = function() {
console.log('我是函数表达式');
}
fun是变量名,不是函数名。
形参和实参
- 如果实参的个数和形参的个数一致则正常输出结果
- 如果实参的个数多于形参的个数会取到形参的个数
- 如果实参的个数小于形参的个数,多余的形参定义为undefined。
- 简单数据类型传形参,复杂数据类型传实参。
返回值
如果函数没有return,则返回undefined。
arguments
arguments对象,以伪数组的形式存储了所有的实参。
之所以成为“伪数组”,是因为他具有length属性,也可以按索引访问,但是没有真正数组的一些方法,例如pop()
, push()
等等。
arguments是每个函数内置的对象。
作用域
全局作用域:整个script标签或者是一个单独的js文件
局部作用域(函数作用域):在函数内部就是局部作用域
如果在函数内部没有声明直接赋值的变量也属于全局变量
ES6标准以前没有块级作用域
从执行效率来看全局变量和局部变量
(1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
(2)局部变量当程序执行完毕就会销毁,比较节约内存资源
作用域链
只要是代码,就至少有一个作用域。
写在函数内部的叫局部作用域。
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链。
下级作用域可以访问上级作用域的变量。
下级作用域的变量名可以屏蔽上级作用域的变量名。
访问变量时采用就近原则逐级向上查找是否存在变量的定义。
预解析
js引擎运行js分为两步:预解析,代码执行
- 预解析js引擎会把js里面所有的
var
还有function
提升到当前作用域的最前面 - 代码执行按照代码书写的顺序从上往下执行
变量提升和函数提升
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
- 变量提升就是把所有的变量声明提升到当前的作用域最前面不提升赋值操作
- 函数提升就是把所有的函数声明提升到当前作用域的最前面不调用函数
因此函数表达式调用必须写在函数表达式的下面
练习
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
答案
9
9
9
9
9
Uncaught ReferenceError: a is not defined
相当于
function f1() {
var a;
c = 9;
b = 9;
a = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);