JavaScript中的各种骚操作

react开发技巧
vue开发技巧
01.数组去重
正常我们实现数组去重都是通过双层变量或者indexOf的方式。

(1)双层for循环去重

function unique(arr) {
    for(var i=0;i<arr.length;i++) {
        for(var j=i+1;j<arr.length;j++) {
            if(arr[i] === arr[j]) {
                arr.splice(j,1);
                j--
            }
        }
    }
    return arr;
}

(2)利用indexOf去重

function unique(arr) {
    if(!Array.isArray(arr)) {
        console.log('type error!');
        return;
    }
    var array = [];
    for (var i=0;i<arr.length;i++) {
        if(array.indexOf(arr[i]) === -1) {
            array.push(arr[i]);
        }
    }
    return array;
}

但其实有一种更简单的方式:利用Array.from与set去重

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!');
        return;
        }
    return Array.from(new Set(arr));
}

对象数组去重

/*
 * 对象数组去重
 *  arr 为要去重数组
 *  key 为数组中对象的唯一值,字段名为string类型
 */
const unique = (arr, key: string) => {
    const res = new Map()
    return arr.filter(arr => !res.has(arr[key]) && res.set(arr[key], 1))
}

02、截断数组
如果你有修改数组长度为某个固定值的需求,那么你可以试试这个

let arr = [0,1,2,3,4,5];
arr.length = 3;
console.log(array);
Output:[0,1,2];

03、获取数组中的最后一项
通常获取数组最后一项,我们用的比较多的是:

let arr = [0,1,2,3,4,5];
const last = arr[arr.length - 1];
console.log(last);
Output: 5;

但我们也可以通过slice操作来实现:

let arr = [0,1,2,3,4,5];
const last = arr.slice(-1)[0];
console.log(last);
Output: 5;

04、美化你的JSON
日常开发中,会经常使用到 JSON.stringify,但并不清楚他具体有哪些参数,实际上它有三个参数:

json: 必须,可以是数组或Object
replacer: 可选值,可以是数组,也可以是方法
space: 用什么来进行分割
而我们恰恰可以指定第三个参数space的值去美化我们的JSON。

05、数组转化为对象(Array to Object)
数组转化为对象,大多数同学想到的是通过遍历数组,放入空对象的方式:

var obj = {};
var arr = ["1","2","3"];
for (var key in arr) {
    obj[key] = arr[key];
}
console.log(obj);
Output: {0:1,1:2,2:3}

但是有一种比较简单快速的方法,即利用展开运算符展开数组

var arr = ["1","2","3"];
var obj = {...arr};
console.log(obj);
Output:{0:1,1:2,2:3}

06、合理利用三元表达式
有些场景我们需要针对不同的条件,给变量赋予不同的值,往往通过if—else的方式:

const isGood = true;
let feeling;
if (isGood) {
    feeling = 'good';
} else {
    feeling = 'bad';
}
console.log(`I feel ${feeling}`)
Output: I feel good

但是为什么不采用三元表达式呢?

const isGood = true;
const feeling = isGood ? 'good' : 'true';
console.log(`I feel ${feeling}`);
Output: I feel good

这种也是所谓的 Single line (单行)思想,其实就是代码趋向于极简的风格。

07、转换为数字类型(Convert to Number)
常见转换为数字的方式,可能主要通过parseInt() 、Number() 这两种方式:

const age = "30";
const ageConvert = parseInt(age);
console.log(typeof ageConvert);
Output: number;

其实也可以通过 + 操作来实现转换:

const age = "30";
const ageConvert = +age;
console.log(typeof ageConvert);
Output: number

08、转换为字符串类型(Convert to String)
常见转换为字符串的方式,可能主要通过toString()、String() 这两种方式:

let a = 123;
console.log(typeof a.toString());
Output: string

但也可以通过 value + “” 的方式来实现

let a = 123;
console.log(typeof (a + ""));
Output: string

09、性能追踪
如果想要测试一段 js 代码的执行耗时,可以尝试使用 performance :

let start = performance.now();
let sum = 0;
for (let i = 0; i < 100000; i++ ) {
   sum += 1; 
}
let end = performance.now();
console.log(start);
console.log(end);

10、合并对象 (Combining Objects)
合并两个对象使用的最多 API 就是 Object.assign() 了:

const obj1 = {a:1};
const obj2 = {b:2};
console.log(Object.assign(obj1, obj2));
Output:{a:1, b:2}

实际上通过扩展运算符 (spread operator) 会特别简单:

const obj1 = {a:1};
const obj2 = {b:2};
console.log({...obj1, ...obj2});
Output:{a:1, b:2}

11、短路运算(Short-circuit evalutation)
可以通过 && 或 | | 来简化我们的代码,比如:

if (isOnline) { postMessage()};
// 使用 &&
isOnline && postMessage();
// 使用 ||
let name = null || "jerry";

12、数组扁平化(Flattening an array)
数组的扁平化一般会通过递归 或reduce 去实现。

(1) 递归:

var arr = [1,[2,[3,4]]];
function flatten(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++ ) {
        if (Array.isArray(arr[i])) {
             result = result.concat(flatten(arr[i]));
            } else {
            result.push(arr[i]); 
        }
    }
    return result;
}
console.log(flatten(arr));
Output:[1,2,3,4]    

(2) reduce:

var arr = [1,[2,[3,4]]];
function flatten(arr) {
    return arr.reduce(function(prev,next) {
            return prev.concat(Array.isArray(next) ? flatten(next) : next)
        }, []);
}

但是 ES6 提供了一个新方法 flat(depth), 参数 depth ,代表展开嵌套数组的深度,默认值是1

let arr = [1,[2,[3,[4,[5]]]]];
console.log(arr.flat(3));
Output:[1, 2, 3, 4, [5]]

13、求幂运算
平时实现指数运算,用的比较多的应该是 Math.pow(),比如求 2^10:

console.log(Math.pow(2,10));

在 ES7 中引入了指数运算符 **, ** 具有与 Math.pow() 一样的运算结果。

console.log(2**10); // 1024

14、浮点数转为整数 (Float to Integer)
一般将浮点数转化为整数会用到 Math.floor() , Math.ceil() , Math.round() 。但其实使用位运算符 ~ ,>>,<<,|,>>> 也能够实现取整。

console.log(~~5.96); // 5
console.log(5.96 >> 0);// 5
console.log(5.96 << 0);// 5
console.log(5.96 | 0);// 5
// >>> 不可对负数取整
console.log(5.96 >>> 0);// 5

15、Object.create(null)
在 Vue 和 Vuex 的源码中,作者都使用了 Object.create(null) 来初始化一个新对象。为什么不使用更简洁的 {} 呢?我们来看下 Object.create() 的定义:

Object.create(proto,[propertiesObject]);

proto: 新创建对象的原型对象;
propertiesObject: 可选。要添加到新对象上的可枚举的属性(新添加的属性是其自身的属性,而不是其原型链上的属性)。
我们可以对比分别通过 Object.create(null) 和 {} 创建对象的不同:

"Object.create(null) 和 {} 创建对象的区别"

从上图可以看到,通过 {} 创建的对象继承了 Object 自身的方法,如 hasOwnProperty 、toString 等,在新对象上可以直接使用。

而使用 Object.create(null) 创建的对象,除了自身属性之外,原型链上没有任务属性。也就是说通过Object.create(null) 的方式可以创建一个纯净的对象,我们可以自己定hasOwnProperty、toString 等方法,完全不必担心会将原型链上的同名方法覆盖掉。

16、拷贝数组
日常开发中,数组的拷贝是一个经常会遇到的场景。实现数组的拷贝有很多骚技巧。

(1)Array.slice()

const arr = [1,2,3];
const copyArr = arr.slice();

(2)展开操作符

const arr = [1,2,3];
const copyArr = [...arr];

(3)使用 Array 构造函数和展开操作符

const arr = [1,2,3,4];
const copyArr = new Array(...arr);

(4)Array.concat

const arr = [1,2,3,4];
const copyArr = arr.concat();

17、避免多条件并列
开发中有时会遇到多个条件,执行相同的语句,也就是多个 || 的情况:

if (status === "a" || status === "b" || status === "c") {doSomething();}

这种写法语义性、可读性都不太好。可以通过 switch case 或 includes 的方式进行改造。

(1) switch case

switch (case ) {
    case "a":
    case "b":
    case "c":
        doSomeThing();
}

(2) includes

const enum = ["a","b","c"];
if (enum.includes(status)) { doSomeThing(); }    

18.Object.freeze()
在 Vue 的文档中介绍数据绑定和响应时,特意标注了对于经过 Object.freeze() 方法的对象无法进行更新响应。Object.freeze() 方法用于冻结对象,禁止对于该对象的属性进行修改。正是由于这种特性,所以在实际项目中,它有很多的使用场景。

像一些纯展示类的页面,可能存在巨大的数组或对象,如果这些数据不会发生改变,那么你就可以使用 Object.freeze() 将它们冻结,这样 Vue 就不会对这些对象做 setter 或 getter 的转换,可以大大提升性能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值