▊ 函数
声明函数 ↓
function getSum(num1, num2) {
return num1 + num2;
}
// 如果没有返回值,则默认return undefined
形参与实参的匹配 ↓
// 下面的写法都是合法的哦 >_< 猜一下它们的返回值
getSum(1, 2);
getSum(1, 2, 3);
getSum(1);
// 答案揭晓
// 返回3. 形参与实参的个数准确匹配
// 返回3. 多余的实参舍去,以形参可以接受的个数为准;需要注意这样并不会报错
// 返回NaN. 第二个形参没有实参给其传值, 好在它有默认值:undefined;计算后结果当然为NaN;值得注意的是这样也不会报错
arguments的使用 ↓
当不确定有多少个实参需要传递时,可以用arguments
来获取;
JS中,所有函数都内置了一个arguments对象(直接用就行),arguments对象存储了传递的所有实参
arguments是一个伪数组
关于伪数组
首先它不是一个真正的数组,具有如下特征:
❶ 具有length属性
❷ 按索引的方式存储数据
❸ 不具有数组的push,pop等方法
arguments使用案例 ↓
// 求任意个数字的和
function getSum() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(getSum(1));
console.log(getSum(1, 3, 8, 0, 9));
声明函数的第二种方式——匿名函数 ↓
var fun = function() {};
// fun是变量名,不是函数名;匿名函数没有函数名
// 可以这么理解,这个变量fun存的不是值,而是一个函数
// 既然是变量,它的初始化同样可以分两步写:
var fun; // 声明
fun = function(){}; // 赋值
▊ 作用域
▍全局与局部
EC6之前,分为全局作用域和局部作用域
变量也对应分为全局变量和局部变量
需要注意的是,不声明直接赋值的变量也是全局变量:a = 233;
从执行效率的角度来看,尽量少使用全局变量
▍块级作用域
目前可以认为JS没有块级作用域
这是个比较微妙的区别用Java和JS举个例子一看便知:
if(true) {
int n = 233;
}
System.out.println(n); // Java绝不会允许你这么做
if(true) {
var n = 233;
}
console.log(n); // 在JS中没有这么严格
※ 别把块级作用域和函数体搞混了。函数体会出现局部变量,外部当让不能使用。
▍作用域链
其实我们在潜意识一直是遵守这个原则的,这里提一下作为依据:
作用域链就是"一层一层向上找",就是"覆盖"
var n = 233
function func1() {
var n = 65535
function func2() {
console.log(n)
}
func2();
}
func1();
// 输出65535.
// 可以理解为 n=65535 把 n=233 覆盖掉了
// 很简单的demo,但有助于我们理解作用域链是什么
▍预解析
先给几个坑,自行先体会:
console.log(a); // 当然报错
console.log(n); // 输出 undefined
var n = 233;
func();
function func() {
console.log('Loli Saikou!'); // 这当然是可以的
}
fun();
var fun = function() {
console.log('Loli Suki!'); // 这样会报错
}
☀ 下面揭晓答案
我们都知道JS代码是由浏览器的JS引擎执行的。JS引擎在运行JS代码时分两步:预解析;代码执行
代码执行不必多说,脚本语言逐行执行;
预解析就是把js代码里的所有var
还有function
提升到当前作用域的最前面。预解析是两方面的:
❶ 变量预解析( 变量提升):把所有的变量声明提升到当前作用域的最前面,不提升赋值操作
❷ 函数预解析( 函数提升):把所有的函数声明提升到当前作用域的最前面(函数的声明包括函数体)
☀ 案例
// 结果是几?
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
// 需要提升的东西有点多,因此先根据预解析的规则转化一下代码,再逐行执行
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun();
// 1.变量预解析,函数预解析
// 2.提升到当前作用域的最前面,注意函数内部也要预解析(作用域是这个函数体)
// 3.因为函数内部的声明将外部已被赋值的num覆盖掉了,因此答案是:undefined
// 陷阱题
function fun() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
fun();
console.log(c);
console.log(b);
console.log(a);
// 预解析不必多说,自己转化一下;真正的陷阱在于这两条语句的微妙区别:
var a = 9, b = 9, c = 9; // 声明并复制了三个变量
var a = b = c = 9; // 声明了a,然后给a,b,c赋值(并没有声明b,c)
// 后者等价于 var a = 9; b = 9; c = 9; b和c变成了全局变量
// 答案为:9 9 9 9 9 报错
☀ Loli & JS
♫ Saikou