js小技巧--摘录1

原文地址https://github.com/loverajoel/jstips

1、数组中插入元素

a.尾部追加

var arr = [1,2,3,4,5];
var arr2 = [];
arr.push(6);
arr[arr.length] = 6;
arr2 = arr.concat([6]);
//快慢排序
1. arr[arr.length] = 6; // 平均42 345 449 ops/sec 2. arr.push(6); // 慢34.66% 3. arr2 = arr.concat([6]); // 慢85.79%

b.头部追加

ar arr = [1,2,3,4,5];
arr.unshift(0);
[0].concat(arr);
//最快的为
1. [0].concat(arr); // 平均4 972 622 ops/sec
2. arr.unshift(0); // 慢64.70%

c.数组中间插入元素

var items = ['one', 'two', 'three', 'four'];
items.splice(items.length / 2, 0, 'hello');

 

2、if嵌套语句的优化

if (color) {
  if (color === 'black') {
    printBlackBackground();
  } else if (color === 'red') {
    printRedBackground();
  } else if (color === 'blue') {
    printBlueBackground();
  } else if (color === 'green') {
    printGreenBackground();
  } else {
    printYellowBackground();
  }
}
//可以改写为
var colorObj = {
  'black': printBlackBackground,
  'red': printRedBackground,
  'blue': printBlueBackground,
  'green': printGreenBackground,
  'yellow': printYellowBackground
};


if (color in colorObj) {
  colorObj[color]();
}

3、sort排序含音节字符的字符串

Javascript有一个原生方法sort可以排列数组。一次简单的array.sort()将每一个数组元素视为字符串并按照字母表排列。你也可以提供自定义排列方法

['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort();
// ["Buenos Aires", "Mumbai", "New York", "Shanghai"]

//下面非ASCLL元素失效,sort只在英文下生效
// 西班牙语
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // bad order

// 德语
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // bad order

处理办法:由ECMAScript国际化API提供的localeCompareIntl.Collator

['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) {
  return a.localeCompare(b);
});
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) {
  return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]

['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare);
// ["árbol", "cosas", "fútbol", "único"]

['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "wäre", "Woche", "wöchentlich"]

 

4、使用严格模式

程序员喜欢电脑帮我们做一些无聊的工作,喜欢它自动的检查我们工作上的错误。这就是”use strict”帮我们做的,它把我们的错误转变为了JavaScript错误。

// 全脚本严格模式
"use strict";
var v = "Hi!  I'm a strict mode script!";

//或者
function f()
{

  // 方法级严格模式
  'use strict';
  function nested() { return "And so am I!"; }
  return "Hi!  I'm a strict mode function!  " + nested();
}
function f2() { return "I'm not strict."; }

通过在JavaScript文件或方法内引入此指令,使JavaScript引擎运行在严格模式下,这直接禁止了许多大项目中不受欢迎的操作。另外,严格模式也改变了以下行为:

  • 只有被”var”声明过的变量才可以引用
  • 试图写只读变量时将会报错
  • 只能通过”new”关键字调用构造方法
  • “this”不再隐式的指向全局变量
  • 对eval()有更严格的限制
  • 防止你使用预保留关键字命名变量

严格模式对于新项目来说是很棒的,但对于一些并没有使用它的老项目来说,引入它也是很有挑战性的。如果你把所有js文件都连接到一个大文件中的话,可能导致所有文件都运行在严格模式下,这可能也会有一些问题。

它不是一个声明,而是一个表达式,被低版本的JavaScript忽略。 严格模式的支持情况:

  • Internet Explorer 10+
  • Firefox 4+
  • Chrome 13+
  • Safari 5.1+
  • Opera 12+

5、将node list转为数组

querySelectorAll方法返回一个类数组对象称为node list。这些数据结构被称为“类数组

 

const nodelist = document.querySelectorAll('div');
const nodelistToArray = Array.apply(null, nodelist);
//或者
const nodelistToArray = Array.prototype.slice.call(nodelist);
const nodelistToArray = [...document.querySelectorAll('div')]; // 返回一个真正的数组
//之后 .. 

nodelistToArray.forEach(...);
nodelistToArray.map(...);
nodelistToArray.slice(...);

6、检查对象是否存在某属性

var myObject = {
  name: '@tips_js'
};


if (myObject.name) { ... }
//这样可以
//同时用hasOwnProperty和in操作符可以区分属性是继承的还是自身的
var myObject = {
  name: '@tips_js'
};

myObject.hasOwnProperty('name'); // true
'name' in myObject; // true


myObject.hasOwnProperty('valueOf'); // false, valueOf 继承自原型链
'valueOf' in myObject; // true

7、contains功能

 位操作符 ~, “按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。”

它将-1转换为0,而0在javascript为false,所以:

var someText = 'text';
!!~someText.indexOf('tex'); // someText contains "tex" - true
!~someText.indexOf('tex'); // someText NOT contains "tex" - false
~someText.indexOf('asd'); // someText doesn't contain "asd" - false
~someText.indexOf('ext'); // someText contains "ext" - true
//在ES6中提供了includes() 方法供我们判断一个字符串是否包含了另一个字符串:
'something'.includes('thing'); // true
//在ECMAScript 2016 (ES7)甚至可能将其应用于数组,像indexOf一样:
!!~[1, 2, 3].indexOf(1); // true
[1, 2, 3].includes(1); // true

8、快速但是危险的取整方法(~~)

一个按位非操作符~首先将输入input截取为32位,然后将其转换为-(input+1)。因此双按位非操作符将输入转换为-(-(input + 1)+1),使其成为一个趋向于0取整的好工具。对于数字的输入,它很像Math.trunc()。失败时返回0,这可能在解决Math.trunc()转换错误返回NaN时是一个很好的替代。

console.log(~~47.11)  // -> 47
console.log(~~1.9999) // -> 1
console.log(~~3)      // -> 3
console.log(~~-3.66)      // -> -3

 

当处理大数时

因为~首先将数组转换为32位,~~的结果伪值在 ±2.15*10^12左右。如果你没有明确的检查输入值的范围,当转换的值最终与原始值有很大差距时,用户就可能触发未知的行为:

a = 2147483647.123  // 比32位最大正数,再多一点
console.log(~~a)    // ->  2147483647     (ok)
a += 10000          // ->  2147493647.123 (ok)
console.log(~~a)    // -> -2147483648     (huh?)

9.安全拼接字符串

var one = 1;
var two = 2;
var three = '3';

var result = ''.concat(one, two, three); //"123"

10、对数组进行洗牌

这段代码运用了优秀的Fisher-Yates Shuffling算法对数组进行洗牌

        const shuffle = arr => {
            for (let i = arr.length - 1; i > 0; i--) {
                let j = ~~(Math.random() * (i + 1));
                [arr[i],arr[j]] = [arr[j],arr[i]]
            } 
            return arr;
        }
var a = [1, 2, 3, 4, 5, 6, 7, 8];
var b = shuffle(a);
console.log(b);
// [2, 7, 8, 6, 5, 3, 1, 4]

11、清空数组的两种方法

// 定义一个数组
var list = [1, 2, 3, 4];

    //清空数组
    list = [];
    
    //或者
    list.length = 0;
  • list = [] 将一个新的数组的引用赋值给变量,其他引用并不受影响。 这意味着以前数组的内容被引用的话将依旧存在于内存中,这将导致内存泄漏。

  • list.length = 0 删除数组里的所有内容,也将影响到其他引用。

 然而,如果你复制了一个数组(A 和 Copy-A),如果你用list.length = 0清空了它的内容,复制的数组也会清空它的内容。

var foo = [1,2,3];
var bar = [1,2,3];
var foo2 = foo;
var bar2 = bar;
foo = [];
bar.length = 0;
console.log(foo, bar, foo2, bar2);

//[] [] [1, 2, 3] []

 

posted @ 2018-11-01 20:39  逸丶风  阅读(209)  评论(0编辑  收藏  举报