Javascript的一些坑点

在使用JS进行程序设计时,偶尔会遇到最终的结果与预期不同的情形,我将导致这种情况的因素称为坑点。

1、Array.prototype.sort([fn])

需要对数组原地稳定排序时,可以使用 arr.sort(fn), 但别忘了指定排序规则函数fn(a,b),否则会按元素的unicode码大小升序排序,如[1,2,10] => [1,10,2]

2、Number类型运算

js中无整数,只有IEEE754标准的双精度64位浮点数,因此做加减乘除运算的时候会很坑:

// 第一个坑点
0.1 + 0.2 不等于 0.3       // 0.30000000000000004
0.3 -0.1 不等于 0.2    // 0.19999999999999998
0.1 * 0.2 不等于0.02       //0.020000000000000004

解决办法1是 parseFloat((5/3).toPrecision(12)) 来解决绝大部分的0.0..01和0.99.。99

解决办法2是 将小数转化成整数,再运算,再转换成小数。

当需要求一个被除数与除数的商和余数时,千万别套用C++的那一套

// C++
int a = 5/3;   // 1
int b = 5%3;   // 2

// JS
let a = 5/3     // 1.6666666666666667
let b = 5%3     // 2

解决办法是向下取整 let a = Math.floor(5/3); // 适用于求商,其他运算以此类推

3、引用类型

拿数组举例,当回溯过程中需要用到数组来返回结果时:

function ruc(arr, res) {
    if(end_situation) res.push(arr);
    ...
    ruc(arr);
    ...
}

如果这样写的话,最后结果毫无意外一定是

[[],[],[],...,[]]
或者
[[same],[same],...,[same]]

所以需要在传递前做一次 仅适合于一维数组的深拷贝

JSON.parse(JSON.stringify(arr));
or
arr.slice();
or
Object.assign([],arr);

4、二维数组

JS是无法像C++一样直接int arr[][] 或 int * arr[] 创建一个二维数组的,会稍微繁琐些,当我想创建一个1到9的3X3矩阵时:

[   
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

在起初,可能会这样做(错误

let arr = [], num = 0;
for(let i=0;i<3;i++) {
    for(let j=0;j<3;j++) {
        arr[i][j] = ++num;
    } 
}

报错 TypeError: Cannot set property '0' of undefined 很显然,arr[0]是undefined,这种写法不对。

于是改成这样(也是错误

let arr = [], num = 0;
// -------新增代码段开始-----------
let tmp = [];
for(let i=0;i<3;i++) {
    arr.push(tmp);
}
// -------新增代码段结束--------------
for(let i=0;i<3;i++) {
    for(let j=0;j<3;j++) {
        arr[i][j] = ++num;
    } 
}

打印结果为[ [ 7, 8, 9 ], [ 7, 8, 9 ], [ 7, 8, 9 ] ] 很显然,又是引用的问题,有两种解决办法
(1)如第四点所说,在arr.push(tmp)中将tmp深拷贝再传递
(2)改成下面这种写法(正确)

let arr = [], num = 0;
for(let i=0;i<3;i++) {
    let tmp = [];
    for(let j=0;j<3;j++) {
        tmp.push(++num);
    }
    arr.push(tmp); 
}

还可以用(正确

let arr = new Array(3), num = 0;
for(let i=0;i<3;i++) {
    arr[i] = new Array(3);
    for(let j=0;j<3;j++) {
        arr[i][j]= ++num;
    }
}

这种写法和第一种错误写法思路很类似了,使用new Array([size])还能规定长度。

如果想采用ES6来创建,这样写是(错误)的,依旧是引用的问题

let arr = new Array(3).fill(new Array(3));
let num = 0;
for(let i in arr) for(let j in  arr) arr[i][j]=++num;

打印 [ [ 7, 8, 9 ], [ 7, 8, 9 ], [ 7, 8, 9 ] ],
正确做法如下:

let arr = Array.from(Array(3), () => new Array(3))
let num = 0;
for(let i in arr) for(let j in  arr) arr[i][j]=++num;

另外需要留意的是遍历中会有坑的点:
(1)用arr.length取矩阵的高/行数, arr[0].length取矩阵的宽/列数
(2)arr[i][j] 表示 第i个一维数组的第j个元素; 也表示 第ij列的元素

5、运算符优先级

举个例子: 1与2异或等于3,那么按我们的常规思维来说来说 1^2 > 1 应该是得到布尔值true的,但是实际上返回0

1^2 > 1
等价于
1^(2>1)

这是因为运算符优先级左/右关联导致的,需要时查阅MDN运算符优先级
为了避免运算符这个坑,按自己的思路加小括号()强制优先运算即可,如(1^2)> 1

6、Array.prototype.splice(start, delete_cnt, item1, item2, item3, ...)

用splice删除或插入元素时,数组长度会变,在搭配循环使用时需要留意索引的回退等等

for(let i=0;i<arr.length;i++) {
    if(condition) {
        arr.splice(i, 1);
        // 注意回退索引:
        i--;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容