函数
函数定义方式-1
function abs (x) {
函数标记 函数名 参数
return x > 0 ? x : -x;
}
函数定义方式-2
var abs = function(x) {
匿名函数
return x > 0 ? x : -x;
};
- 两种定义方式等价
- 使用匿名函数定义时注意最后的分号
- return返回结果,若无返回undefined
- 因为JavaScript自动加分号机制,return后尽量不要换行。
函数 - 参数
- 函数的规定参数,和实际参数不一定一致(不会报错)。
- 传入参数多时,多余的参数不会生效(因为函数体没有
直接
用的地方) - 也可以少传,但规定参数值为undefined
arguments对象:在函数体内有效,指向传入的所有参数
- 对象在函数体内置,不需声明可直接使用
- 使用方法同Array,但实际不是Array
用法1: 接收所有参数,并后续使用,例如 求和
用法2: 将某个参数设为可选参数,根据arguments的长度判断传入参数的形式。
rest对象: ES6
将规定外的多余参数以数组形式存放在rest中
- rest参数只能放在最后,前面用
...
标识 - 当参数不多余规定参数时,rest对象以空数组的形式存在
function eg(first, second, ...rest) {
//.....
}
全局对象 window
- 全局作用域的变量被绑定到window对象上
- 自定义的函数实际上也是一个全局变量
?? 名称空间与多个文件共享window不明确,20181107记录
var
VS let
变量提升 Hoisting
JavaScript对于var声明的变量,会在编译阶段将声明字段提高函数内第一行。JavaScript 仅提升声明,而不提升初始化,也就是说,var只能声明全局变量或函数级变量。
var z = 2;
console.log(x);
console.log(y);
console.log(z);
var x = 1;
// OUTPUT
Exception: ReferenceError: y is not defined
去掉console.log(y);后
15:13:41.580 undefined
15:13:41.581 2
总结:
- 没有声明y,使用y时,会提示异常
- 由于变量提升,在输出后声明x,不提示错误
- 变量提升只提升声明,不提升初始化,所以x输出的是undefined
var | let |
---|---|
全局变量,或函数级变量 | 语句块级别变量,作用域仅在 {...} 中 |
可以对同一个变量多次使用var | 同一个语句块内多次使用let会提示错误 |
建议:
- 使用名字空间
- 在函数内部首先声明所有使用到的变量
常量 ES6
const定义常量,与let一样为块作用域。常量不能再次赋值。
解构赋值 ES6
简单来说:从数组、对象等元素中同时对多个变量赋值,简单实用。
注意
- 变量声明层次与数组、对象层次一致,修饰符(
[
或{
)一致 - 可以忽略一些赋值,使用逗号空出某个变量
- 使用对象的解构赋值时,要与对象的属性名称相同
- 对象内还有对象示例:var {name, address: {city, port}} = person;
用法示例
- 改变对象对应变量名
var person = {
name: "Bob",
phone: '157****2333'
};
var {name, phone:mobile} = person;
console.log(`name: ${name}, mobile: ${mobile}`);
// OUTPUT
name: Bob, mobile: 157****2333
- 使用默认值
var person = {
name: "Bob",
address: {
city:"zz",
post: '475000'
}
};
var {name, address:{city, level='five'}} = person;
console.log(`name: ${name}, city: ${city}, level: ${level}`);
// OUTPUT
name: Bob, city: zz, level: five
- 交换值
var x = 1, y = 1000;
[x,y] = [y,x];
console.log(`x: ${x}, y: ${y}`);
// OUTPUT
x: 1000, y: 1
- 解析域名与路径
var {hostname,pathname} = location;
console.log(`hostname:${hostname}, pathname:${pathname}`);
// OUTPUT
hostname:blog.csdn.net, pathname:/qq_21282443/article/details/83793265
- 函数体参数写成解构函数形式,可以是传递参数时直接传递对象或数组
function toString({name,age,address:{city,post}}) {
console.log(`
name: ${name},
age: ${age},
// address: ${address}, 此行注释,参数中并没有传递address参数,只是层次说明
city: ${city},
post: ${post}
`);
}
var person = {
name:'BOB',
age: 18,
address:{
city:'zz',
post:'12306'
}
}
toString(person);
// OUTPUT
name: BOB,
age: 18,
city: zz,
post: 12306
方法
之前有说过函数function
的用法,将匿名函数绑定到对象的属性,称之为这个对象的方法
var person = {
name: 'Bob',
birth: 1995,
age: function() {
var date = new Date().year;
return year - this.birth;
}
}
console.log(person.age);
console.log(person.age());
// OUTPUT
17:54:43.470 function age()
17:54:43.471 23
**其中this有大坑,因为this指向的对象不明确,在非严格模式下指向当前调用的对象,慎用,毕竟现在不太懂 **
apply(): 指定函数中this指向那个对象,函数本身都有这个方法。
function whoami() {
return this;
}
var obj = {};
whoami.apply(obj, []);
// whoami为函数名,负责调用apply方法
// obj 第一个参数,将this绑定到此对象,普通方法(不使用this)可绑定为null
// [] 参数,whoaami函数需要的参数,以数组形式传递
call(): 与apply()用法一致,最大区别是传递参数时,call()将参数顺序传递,apply将参数包装到数组中
Math.max(3, 5, 2); // Math的最大值方法
Math.max.apply(null, [3, 5, 2]); // apply方法使用方式
Math.max.call(null, 3, 5, 2); // call方法使用方式