【JavaScript】小细节防坑积累(持续更新)

1. 使用"逻辑或"设置初始值

此方法不识别数值 0:【0 被转为布尔值 false,跳过执行】

function fn(val) {
	return val = val || '默认值';
}

fn(0);	// '默认值'
fn();	// '默认值'

应改为 “if” 语句:

function fn(val) {
	if (val !== 0) val = val || '默认值';
	return val;	// 注意,判断不含 0,所以返回值要单独写
}

fn(0);	// 0
fn();	// '默认值'

或改为三元表达式:

function fn(val) {
	return val = (val === 0 ? 0 : (val ? val : '默认值'));
}

fn(0);	// 0
fn();	// '默认值'

2. 初始值为 undefined 与 null 的区别

在运算时,"undefined"会被转为数值 NaN,“null” 则被转为数值 0。
另外,0 是数值中的空值。

undefined == null;	// true
undefined === null;	// false

isNaN(undefined);	// true
isNaN(null);		// false

var a = a || undefined;
a + 1;	// NaN

var b = b || null;	// 等同于 var b = b || 0;
b + 1;	// 1

3. 计算时避免运算子进行字符串拼接

有时候需要一个参数既可以为字符串,又可以为数值。
但在 JavaScript 中,只要其中一个运算子为字符串,相加时都将会进行拼接运算:

function fn(val) {
	return val + 1;
}

fn('1');	// '11'

转换方法有很多,最常用的是【减乘除指数算术运算符】、【Number()】:

function fn(val) {
	return val/1 + 1;
	// (val - 0)
	// val * 1
	// val ** 1
	// Number(val) + 1;
}

fn('1');	// 2

4. 为了易读与排错,应谨慎(尽量不使用)“短路”

"短路"规则不适用于多条执行,否则易出错:【没有判断控制,会优先执行最上面一条】

function fn(a, b) {
    return isNaN(a) || isNaN(b) ? '不是数字' : '是数字';	// 优先执行
    return a > 10 || b < 0 ? '非法值' : '合法值';	// 永远不执行
}

fn('a', 'b');	// '不是数字'
fn(11, -1);		// '是数字'

应改为 “if” 语句:

function fn(a, b) {
    if (isNaN(a) || isNaN(b)) return '不是数字';
    if (a > 10 || b < 0) return '非法值';
}

fn('a', 'b');	// '不是数字'
fn(11, -1);		// '非法值'

5. 函数体内覆盖变量值

  • 错误写法:
var num = 123;
function fn(n) {
	n = 999;
}

fn(num);
num;	// 123

这是由于形参相当于在函数内部隐式声明的局部变量,所以无法覆盖外部变量。

  • 相当于:
var num = 123;
function fn() {
	var num = 999;
}

fn();
num;	// 123
  • 正确写法:
// 内部直接覆盖
var num = 123;
function fn() {
	num = 999;
}

fn();
num;	// 999

/* ----------------------------------------------- */
// 函数返回一个结果,赋值给原变量
var num = 123;
function fn() {
	n = 999;
	return n;
}

num = fn();
num;	// 999;

6. 关于数据转换为字符串

  • 错误用法
// 数组、对象:无法直接转为字符串
([]).toString();					// ''	【某些时候则有用】
({}).toString();					// '[object Object]'

// 正则、函数、undefined:无法通过 stringify() 正确获取字符串
JSON.stringify(new RegExp);			// '{}'
JSON.stringify(function() {});		// undefined
JSON.stringify(undefined);			// undefined

// 数组存在 null、undefined 元素时:
[null, undefined].toString();		// ','
JSON.stringify([null, undefined]);	// '[null,null]'
  • 正确用法【逐个对应】:
// 数组、对象:使用 stringify() 方法
JSON.stringify([]);					// '[]'
JSON.stringify({});					// '{}'

// 正则、函数、undefined:直接转换
(new RegExp).toString();			// '/(?:)/'
(function() {}).toString();			// 'function() {}'
undefined+'';						// 'undefined'

// 数组存在 null、undefined 元素时,遍历拆分,分别转为字符串再重组
var _arr = [null, undefined];
var getStr = function(arr) {
	var item = '';
	for (var i = 0, len = arr.length; i < len; i++) {
		if (i < len-1) {
			item += arr[i] + ',';
		} else {
			item += arr[i] + '';
		}
	}
	return '[' + item + ']';
}

getStr(_arr);						// '[undefined,null]'

7. typeof 无法正确判断的数据类型

// 对象、数组、日期、正则均判断为对象(它们都是对象类型)
typeof {};			// 'object'
typeof [];			// 'object'
typeof /^$/;		// 'object'
typeof (new Date);	// 'object'


// null 是特殊的对象
typeof null;		// 'object'

8. instanceof 无法正确判断的数据类型

在这里插入图片描述
在这里插入图片描述

// 由于instanceof检查整个原型链,因此同一个实例对象,可能会对多个构造函数都返回true
([]) instanceof Array;			// true
([]) instanceof Object;			// true
(new Date) instanceof Date;		// true
(new Date) instanceof Object;	// true

// 不能用来判断原始值
'str' instanceof String;		// false
  • 可以通过 Object.prototype.toString.call(); 来区分引用类型数据
Object.prototype.toString.call({});				// '[object Object]'
Object.prototype.toString.call([]);				// '[objcet Array]'
Object.prototype.toString.call(function(){});	// '[object Function]'
Object.prototype.toString.call(new Date);		// '[object Date]'
Object.prototype.toString.call(/^$/);			// '[object RegExp]'

9. 递归需 return 才会有返回值

  • 错误写法
// 倒数获取与 '<!>' 之间不超过 5 个元素的 '' 的位置
const arr = [
  '',
  '',
  'asd',
  '',
  'asdasd',
  'xxx',
  '',
  '<!>',
  '',
  'sdas'
];
const end = arr.indexOf('<!>');

const start = (function getIndex(i) {
  let index = arr.lastIndexOf('', i);
  if (end - index < 5) {
    i--;
    getIndex(i);	// 没有 return
  } else {
    return index;
  }
})(end);

console.log(start);	// undefined
  • 正确写法
// 倒数获取与 '<!>' 之间不超过 5 个元素的 '' 的位置
const arr = [
  '',
  '',
  'asd',
  '',
  'asdasd',
  'xxx',
  '',
  '<!>',
  '',
  'sdas'
];
const end = arr.indexOf('<!>');

const start = (function getIndex(i) {
  let index = arr.lastIndexOf('', i);
  if (end - index < 5) {
    i--;
    return getIndex(i);	// 此处也需要 return
  } else {
    return index;
  }
})(end);

console.log(start);	// 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值