函数
第一种function定义函数;
function a(x) { if (x >= 0) { return x; } else { return -x; } }
第二种匿名函数赋值给变量;
var abs = function (x) { if (x >= 0) { return x; } else { return -x; } };
arguments是函数内起作用的关键字,指向当前函数传入的所有参数,类似Array但不是;
function foo(x) { console.log('x = ' + x); // 10 for (var i=0; i<arguments.length; i++) { console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30 } } foo(10, 20, 30);
rest参数用...标识,获取多余的参数;
function foo(a, b, ...rest) { console.log('a = ' + a); console.log('b = ' + b); console.log(rest); } foo(1, 2, 3, 4, 5); // a = 1 // b = 2 // Array [ 3, 4, 5 ] foo(1); // a = 1 // b = undefined // Array []
作用域
var声明变量在函数内,就不能在外面引用。
函数能够嵌套,内部函数可以访问外部函数定义的变量。
不在函数内定义的变量都是全局变量,JavaScript默认有一个全局对象window,全局变量实际上被绑定为window的属性。
var course = 'Learn JavaScript'; alert(window.course); // 'Learn JavaScript' function foo() { alert('foo'); } window.foo(); // 通过window.foo()调用 window.alert('调用window.alert()'); //alert也是window的变量
由于全局变量都会绑定到window上,不同的JavaScript文件如果使用相同全局变量,或者相同函数名,那么会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中;
// 唯一的全局变量MYAPP: var MYAPP = {}; // 其他变量: MYAPP.name = 'myapp'; // 其他函数: MYAPP.foo = function () { return 'foo'; };
由于在for循环等语句块中无法定义局部变量,所以ES6引入了let关键字,声明块作用域变量;
function foo() { for (var i=0; i<100; i++) { } i += 100; // 仍然可以引用变量i } function foo() { var sum = 0; for (let i=0; i<100; i++) { sum += i; } // 报错: i += 1; }
const定义常量,也有块作用域。
解构赋值也就是多变量赋值,变量和值用[]包起来,如果值本身有嵌套,那么变量和它一样嵌套就行了。
let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']]; x; // 'hello' y; // 'JavaScript' let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前两个元素,只对z赋值第三个元素
如需要从对象取出若干属性,也可以使用解构赋值;
var person = { name: '小明', age: 20, gender: 'male', }; var {name, age} = person; console.log('name = ' + name + ', age = ' + age ); //name = 小明, age = 20
同样可以直接对嵌套的对象属性进行赋值,只要层次一致:
var person = { name: '小明', address: { city: 'Beijing', street: 'No.1 Road', zipcode: '100001' } }; var {name, address: {city, zip}} = person; name; // '小明' city; // 'Beijing' zip; // undefined, 因为属性名是zipcode而不是zip // address不是变量,而是为了让city和zip获得嵌套的address对象的属性: address; // Uncaught ReferenceError: address is not defined