函数
- 函数声明尽量不要采用匿名函数,错误栈无法准确定位问题
- 不要在非函数块(
if、while等)内声明函数
//bad
if (true) {
function fTest() {
console.log('bad')
};
fTest()
}
//good
const fTest;
if (true) {
fTest = () => console.log('good');
fTest()
}
- 传参不要用
arguments;优先级高于函数作用域自带的arguments,会被覆盖 - 用
...语法收集函数传参,不要使用arguments
//bad
function fConcatAll() {
const args = Array.from(arguments);
return args.join('')
}
//good
function fConcatAll1(...args) {
return args.join('')
}
const sConcat = fConcatAll(1, 2, 3);
const sConcat1 = fConcatAll1(1, 2, 3);
console.log('sConcat', sConcat);
console.log('sConcat1', sConcat1);
//sConcat 123
//sConcat1 123
- 用默认参数语法赋值;且把默认参数赋值放在传参最后
function fDefaultVal(opt, opt1 = 1, opt2 = 2) {
console.log('opt',opt);
console.log('opt1',opt1);
console.log('opt2',opt2);
};
fDefaultVal(1, 2)
//opt 1,
//opt1 2
//opt2 2
插曲1:函数call使用说明
//call方法可以让不具备某个方法的对象使用对应的方法
const oTest = {
fGetAction (...args) {
return `${this.firstName} is ${args.join(' and ')}`
}
};
const oPerson = {
firstName: 'Billy'
};
//并且call方法可以传参
const sWord = oTest.fGetAction.call(oPerson, 'moving','shaking');
console.log(sWord);
//Billy is moving and shaking
插曲2:判定对象含有键值
//不具备原型链上同名属性
const oTest = {
name: 'Billy'
};
oTest.hasOwnProperty('name'); //true
//此处调用对象不存在该方法,会向上找原型链上对应的方法,使用的原型链方法
//存在同名属性hasOwnProperty
const oTest1 = {
name: 'Sam',
hasOwnProperty: () => false
};
oTest1.hasOwnProperty('name'); //false
//此处对象内置方法与原型链方法同名,并未指定调用原型链方法,所输出始终为false
Object.prototype.hasOwnProperty.call(oTest1, 'name'); //true
//Object.prototype是所有对象的原型链顶层,所以如此调用可以确保采用原型链顶端的方法
- 不要修改参数值,内部调用可定义局部变量重新赋值,改变原始数据会使原始调用混乱
function fChangeKey(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
}
function fChangeVal(a) {
const b = a || 1;
}
function fChangeVal1(a = 1) {}