模板
function abs(x) { if (x >= 0) { return x; } else { return -x; } }
可以看到,不需要声明函数返回值。
没有return语句,函数执行完毕后也会返回结果,只是结果为undefined
abs()函数实际上是一个函数对象,而函数名abs可以视为指向该函数的变量
var abs = function (x) { if (x >= 0) { return x; } else { return -x; } };
注意:由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数。
内部成员,arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数
//类似一个参数数组 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); x = 10 arg 0 = 10 arg 1 = 20 arg 2 = 30
ES6新语法: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 ]
变量作用域
内部函数可以访问外部函数定义的变量,反过来则不行
function foo() { var x = 1; function bar() { var x = 'A'; console.log('x in bar() = ' + x); // 'A' } console.log('x in foo() = ' + x); // 1 bar(); } foo(); x in foo() = 1 x in bar() = A
变量提升
JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值
所以还是像Java那样在使用之前初始化好吧。
(console.log显示Hello, undefined)
function foo() { var y; // 提升变量y的申明,此时y为undefined var x = 'Hello, ' + y; console.log(x); y = 'Bob'; }
全局作用域
不在任何函数内定义的变量就具有全局作用域。
实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:
var course = 'Learn JavaScript'; alert(course); // 'Learn JavaScript' alert(window.course); // 'Learn JavaScript'
每次直接调用的alert()函数其实也是window的一个变量
命名空间
全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中
// 唯一的全局变量MYAPP: var MYAPP = {}; // 其他变量: MYAPP.name = 'myapp'; MYAPP.version = 1.0; // 其他函数: MYAPP.foo = function () { return 'foo'; };
把自己的代码全部放入唯一的名字空间MYAPP中,会大大减少全局变量冲突的可能。
许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。
Let
由于JavaScript的变量作用域实际上是函数内部
我们在for循环等语句块中是无法定义具有局部作用域的变量的
function foo() { for (var i=0; i<100; i++) { // } i += 100; // 仍然可以引用变量i }
不能像java一样,定于只属于循环内部的变量i。JS只要是函数内部定义了的变量,整个函数内部都能访问。
为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:
function foo() { var sum = 0; for (let i=0; i<100; i++) { sum += i; } // SyntaxError: i += 1; }
常量
ES6语法 const
ES6语法以前是没有区分常量的声明的,只能var
const PI = 3.14; PI = 3; // 某些浏览器不报错,但是无效果! PI; // 3.14
解构赋值
ES6新语法,很有用,但是不展开了,还有很多很复杂的用法
其实就是一种语法糖,有没有都还可以吧,至少现在我是这么想的
let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']]; x; // 'hello' y; // 'JavaScript' z; // 'ES6'
抽取对象成员
var person = { name: '小明', age: 20, gender: 'male', passport: 'G-12345678', school: 'No.4 middle school' }; var {name, age, passport} = person; console.log('name = ' + name + ', age = ' + age + ', passport = ' + passport); //name = 小明, age = 20, passport = G-12345678
交换变量的值
var x=1, y=2; [x, y] = [y, x]