函数 (一)
1. 函数定义和调用
-
定义函数
function abs(x){ if (x>=0){ return x; } else{ return -x; } } // 也可以采用匿名函数形式 abs = function(x){...}
-
调用函数
JavaScript允许传入任意参数而不影响调用,因此调用时要考虑以下情况:- 传入参数少于所需时: 函数返回
NaN
; - 传入参数多于所需时:函数只取需要的参数;
- 当函数存在可选参数时:定义函数时要注意判断参数个数,这时常用
arguments
关键字来判定。
- 传入参数少于所需时: 函数返回
-
arguments
每个函数都自带arguments
关键字,只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments最常用于判断传入参数的个数,如下例:
// foo(a[, b], c) // 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null: function foo(a, b, c) { if (arguments.length === 2) { // 实际拿到的参数是a和b,c为undefined c = b; // 把b赋给c b = null; // b变为默认值 } }
-
rest
参数
rest参数接受多余的函数生成数组。参数只能写在最后,前面用...
标识。function f(a,b,...rest){ ... }
2. 变量作用域与解构赋值
2.1 变量作用域
- 函数内部声明的变量只在函数内部有效;
- 函数内部声明了与外部相同的变量时,将只使用内部变量;
- 变量提升:函数内部各处声明的变量都会预先提到函数开头;
- 不在任何函数内定义的变量就具有全局作用域;
- 名字空间:与C++中的namespace一样,不同JavaScript文件的同名全局变量会冲突。减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:
// 唯一的全局变量MYAPP: var MYAPP = {}; // 其他变量: MYAPP.name = 'myapp'; MYAPP.version = 1.0; // 其他函数: MYAPP.foo = function () { return 'foo'; };
- 常量可用
const
代替var
来定义;
2.2 解构赋值
解构赋值即同时对一组变量进行赋值
[x,y,z]=['hello', 'JavaScript', 'ES6']
//有嵌套时,注意嵌套层次和位置要保持一致
[x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
//从一个对象中取出若干属性,也可以使用解构赋值,同样也支持嵌套:
var person = {
name: '小明',
age: 20,
gender: 'male',
passport: 'G-12345678',
school: 'No.4 middle school',
address: {
city: 'Beijing',
street: 'No.1 Road',
zipcode: '100001'
}
};
var {name, address: {city, zipcode}} = person; //注意是大括号
- 使用场景
// 交换两个变量x和y的值 var x=1, y=2; [x, y] = [y, x]; // 快速获取当前页面的域名和路径: var {hostname:domain, pathname:path} = location; //这里hostname和pathname不是变量,是为了让domain和path获得两者的属性 //如果一个函数接收一个对象作为参数, //那么,可以使用解构直接把对象的属性绑定到变量中。 function buildDate( {year, month, day, hour=0, minute=0, second=0}) { return new Date( year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second); }
3. 方法
在一个对象中绑定函数,称为这个对象的方法。
-
this
关键字
在一个方法内部,this始终指向当前对象。但是在方法内嵌的函数里,this不再指向当前对象,而是指向全局对象window
或undefined
(处在’strict’模式下) -
apply
可以使用apply
方法控制this
指向的对象。它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。function getAge() { var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25 getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
另一个与apply()类似的方法是
call()
,唯一区别是:apply()
把参数打包成Array
再传入;call()
把参数按顺序传入。比如调用Math.max(3, 5, 4),分别用apply()和call()实现如下:
Math.max.apply(null, [3, 5, 4]); // 5 Math.max.call(null, 3, 5, 4); // 5
对普通函数调用,我们通常把this绑定为null。