1、Rest 参数 与 Spread 操作符
当我们在代码中遇到“..."时,它不是Rest参数就是Spread操作符
区分方法:
若...出现在函数的参数列表,那它表示的就是Rest参数,它会把函数多余的实参收集到一个数组中。
1 function sumAll(...args) { // 数组变量名为 args
2 let sum = 0;
3
4 for (let arg of args) sum += arg;
5
6 return sum;
7 }
8
9 alert( sumAll(1) ); // 1
10 alert( sumAll(1, 2) ); // 3
11 alert( sumAll(1, 2, 3) ); // 6
若... 出现在函数调用或类似的表达式中,那么它就是Spread操作符,它会把一个数组展开为逗号分隔的元素列表。
1 let arr = [3, 5, 1];
2
3 alert( Math.max(...arr) ); // 5(Spread 操作符把数组转为参数列表)
1 let str = "Hello";
2
3 alert( [...str] ); // H,e,l,l,o
2、旧时的“var”
“var”没有块级作用域
1 function sayHi() { 2 if (true) { 3 var phrase = "Hello"; 4 let test = "aa" 5 } 6 7 alert(phrase); // works 8 alert(test);//报错 test is not defined 9 } 10 11 sayHi(); 12 alert(phrase); // 报错:phrase is not defined
“var” 在函数开头被处理
1 function sayHi() { 2 phrase = "Hello"; 3 4 alert(phrase); 5 6 var phrase; 7 } 8 和下面等同 9 function sayHi() { 10 var phrase; 11 12 phrase = "Hello"; 13 14 alert(phrase); 15 } 16 17 或者代码块被忽略 18 19 function sayHi() { 20 phrase = "Hello"; // (*) 21 22 if (false) { 23 var phrase; 24 } 25 26 alert(phrase); 27 } 28 此时的变量仍可以被访问
3、全局对象
概念:全局对象提供在任何地方使用的变量和函数。大多情况下,这些局部变量内置与语言或主机环境中。浏览器中它被命名为window。
window 对象
1)作为全局对象外,还有浏览器窗口功能,
alert(window.innerHeight);//显示浏览器窗口高度
window.open('http://www.baidu.com')//打开一个新窗口
2)顶级var 变量和函数声明后自动成为window属性
var x = 5;
alert(window.x)//5 这样可以访问x
但是 let/const 声明不会发生这种情况,因为这两个的声明不会给window 创建属性
3) 正常情况下,所有脚本代码共享相同的全局作用域
1 <script> 2 var a = 1; 3 let b = 2; 4 </script> 5 6 <script> 7 alert(a); // 1 8 alert(b); // 2 9 </script>
4)全局范围内 this 的值为 window
alert(this);//window
这样会可能导致命名冲突
所以现在有了一个解决办法就是给 type设置 “module” 属性
//在一个模块中, var x 不会成为window属性 <script type="module"> var x = 5; alert(window.x); // undefined </script> //两个模块的变量彼此不可见 <script type="module"> let x = 5; </script> <script type="module"> alert(window.x); // undefined alert(x); // 错误:未声明的变量 </script> //在模块中 this 的顶级变量为 undefined <script type="module"> alert(this); // undefined </script>
4、函数对象
属性 “name"
1 function sayHi() { 2 alert("Hi"); 3 } 4 5 alert(sayHi.name); // sayHi
属性 "length"
这个属性是用来返回函数传入参数的个数
function f1(a) {} function f2(a, b) {} function many(a, b, ...more) {} alert(f1.length); // 1 alert(f2.length); // 2 alert(many.length); // 2
但是余参不参与计数
自定义属性
1 function sayHi() { 2 alert("Hi"); 3 4 // 我们记录一下运行次数 5 sayHi.counter++; 6 } 7 sayHi.counter = 0; // 初始值 8 9 sayHi(); // Hi 10 sayHi(); // Hi 11 12 alert( `调用了 ${sayHi.counter} 次` ); // 调用了 2 次
命名函数表达式
1)这个名字允许在函数内部引用自己
2)在函数外部是不可见的
1 2 let sayHi = function func(who) { 3 if (who) { 4 alert(`Hello, ${who}`); 5 } else { 6 func("Guest"); // 使用 func 再次调用自己 7 } 8 }; 9 10 sayHi(); // Hello, Guest 11 12 // 但这个无法生效 13 func(); // Error, func is not defined(在函数外不可见)