We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
写这篇文章的缘由是上周在公司前端团队的code review时,看了一个实习小哥哥的代码后,感觉一些刚入行不久的同学,对于真实项目中的一些js处理不是很熟练,缺乏一些技巧。
code review
js
因此整理了自己开发中常用的一些js技巧,灵活的运用,会增强你解决问题的能力,也会对你的代码简洁性有很大的改观。
正常我们实现数组去重大多都是通过双层遍历或者indexOf的方式。
indexOf
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; }
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去重
Array.from
set
function unique(arr) { if (!Array.isArray(arr)) { console.log("type error!"); return; } return Array.from(new Set(arr)); }
这种代码的实现是不是很简洁 😉
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}
但是有一种比较简单快速的方法:
const arr = [1,2,3] const obj = {...arr} console.log(obj) Output: {0: 1, 1: 2, 2: 3}
一行代码就能搞定的事情为什么还要用遍历呢?😛
有些场景我们需要针对不同的条件,给变量赋予不同的值,我们往往会采用下面这种方式:
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' : 'bad' console.log(`I feel ${feeling}`) Output: I feel good
这种也就是所谓的Single line(单行)思想,其实就是代码趋向于简洁性。
Single line
简洁性
Convert to Number
这种是很常见的,大家用的比较多的可能是parseInt()、Number()这种:
parseInt()
Number()
const age = "69"; const ageConvert = parseInt(age); console.log(typeof ageConvert); Output: number;
其实也可以通过+来实现转换:
+
const age = "69"; const ageConvert = +age; console.log(typeof ageConvert); Output: number;
Convert to String
转换为字符串一般会用toString()、String()实现:
toString()
String()
let a = 123; a.toString(); // '123'
但也可以通过value + ""这种来实现:
value + ""
let a = 123; a + ""; // '123'
如果你想测试一段js代码的执行耗时,那么你可以尝试下performance:
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);
Combining Objects
两个对象合并大家用的比较多的可能就是Object.assign了:
Object.assign
const obj1 = { a: 1 } const obj2 = { b: 2 } console.log(Object.assign(obj1, obj2)) Output: { a: 1, b: 2 }
其实有一种更简洁的方式:
const obj1 = { a: 1 } const obj2 = { b: 2 } const combinObj = { ...obj1, ...obj2 } console.log(combinObj) Output: { a: 1, b: 2 }
也就是通过展开操作符(spread operator)来实现。
展开操作符(spread operator)
Short-circuit evaluation
我们可以通过&&或||来简化我们的代码,比如:
&&
||
if (isOnline) { postMessage(); } // 使用&& isOnline && postMessage(); // 使用|| let name = null || "森林";
Flattening an array
数组的扁平化,我们一般会用递归或reduce去实现
递归
reduce
var arr = [1, [2, [3, 4]]]; function flatten(arr) { var result = []; for (var i = 0, len = arr.length; i < len; i++) { if (Array.isArray(arr[i])) { result = result.concat(flatten(arr[i])); } else { result.push(arr[i]); } } return result; } console.log(flatten(arr));
var arr = [1, [2, [3, 4]]]; function flatten(arr) { return arr.reduce(function (prev, next) { return prev.concat(Array.isArray(next) ? flatten(next) : next); }, []); } console.log(flatten(arr));
但是es6提供了一个新方法 flat(depth),参数depth,代表展开嵌套数组的深度,默认是1
es6
flat(depth)
depth
1
let arr = [1, [2, 3, [4, [5]]]]; arr.flat(3); // [1,2,3,4,5]
平时我们实现指数运算,用的比较多的应该是Math.pow(),比如求2^10:
Math.pow()
2^10
console.log(Math.pow(2, 10));
在ES7中引入了指数运算符**,**具有与Math.pow()一样的计算结果。
ES7
**
console.log(2 ** 10); // 输出1024
Float to Integer
我们一般将浮点数转化为整数会用到Math.floor()、Math.ceil()、Math.round()。但其实有一个更快的方式:
Math.floor()
Math.ceil()
Math.round()
console.log(~~6.95); // 6 console.log(6.95 >> 0); // 6 console.log(6.95 << 0); // 6 console.log(6.95 | 0); // 6 // >>>不可对负数取整 console.log(6.95 >>> 0); // 6
也就是使用~, >>, <<, >>>, |这些位运算符来实现取整
~
>>
<<
>>>
|
如果你有修改数组长度为某固定值的需求,那么你可以试试这个
let array = [0, 1, 2, 3, 4, 5]; array.length = 3; console.log(array); Output: [0, 1, 2];
通常,获取数组最后一项,我们用的比较多的是:
let arr = [0, 1, 2, 3, 4, 5]; const last = arr[arr.length - 1]; console.log(last); Output: 5;
但我们也可以通过slice操作来实现:
slice
let arr = [0, 1, 2, 3, 4, 5]; const last = arr.slice(-1)[0]; console.log(last); Output: 5;
JSON
日常开发中,我们会经常用到JSON.stringify,但大家可能并不大清楚他具体有哪些参数。
JSON.stringify
他有三个参数:
json
Object
replacer
space
而我们恰恰可以指定第三个参数space的值去美化我们的JSON:
Object.create(null)
在Vue和Vuex的源码中,作者都使用了Object.create(null)来初始化一个新对象。为什么不用更简洁的{}呢? 我们来看下Object.create()的定义:
Vue
Vuex
{}
Object.create()
Object.create(proto,[propertiesObject])
proto
propertiesObject
我们对比分别通过Object.create(null)和{}创建对象的不同: 从上图可以看到,通过{}创建的对象继承了Object自身的方法,如hasOwnProperty、toString等,在新对象上可以直接使用。
hasOwnProperty
toString
而使用Object.create(null)创建的对象,除了自身属性a之外,原型链上没有任何属性。
a
也就是我们可以通过Object.create(null)这种方式创建一个纯净的对象,我们可以自己定义hasOwnProperty、toString等方法,完全不必担心会将原型链上的同名方法覆盖掉。
纯净
日常开发中,数组的拷贝是一个会经常遇到的场景。其实实现数组的拷贝有很多骚技巧。
Array.slice
const arr = [1, 2, 3, 4, 5]; const copyArr = arr.slice();
const arr = [1, 2, 3, 4, 5]; const copyArr = [...arr]
Array
const arr = [1, 2, 3, 4, 5]; const copyArr = new Array(...arr)
Array.concat
const arr = [1, 2, 3, 4, 5]; const copyArr = arr.concat();
开发中有时会遇到多个条件,执行相同的语句,也就是多个||这种:
if (status === 'process' || status === 'wait' || status === 'fail') { doSomething() }
这种写法语义性、可读性都不太好。可以通过switch case或includes这种进行改造。
switch case
includes
switch(status) { case 'process': case 'wait': case 'fail': doSomething() }
const enum = ['process', 'wait', 'fail'] if (enum.includes(status)) { doSomething() }
Object.freeze()
在 Vue 的文档中介绍数据绑定和响应时,特意标注了对于经过 Object.freeze() 方法的对象无法进行更新响应。 Object.freeze() 方法用于冻结对象,禁止对于该对象的属性进行修改。
正是由于这种特性,所以在实际项目中,他有很多的适用场景。
像一些纯展示类的页面,可能存在巨大的数组或对象,如果这些数据不会发生更改,那么你就可以使用Object.freeze()将他们冻结,这样Vue就不会对这些对象做setter或getter的转换,可以大大的提升性能。
setter
getter
The text was updated successfully, but these errors were encountered:
No branches or pull requests
引言 🏂
写这篇文章的缘由是上周在公司前端团队的
code review
时,看了一个实习小哥哥的代码后,感觉一些刚入行不久的同学,对于真实项目中的一些js
处理不是很熟练,缺乏一些技巧。因此整理了自己开发中常用的一些
js
技巧,灵活的运用,会增强你解决问题的能力,也会对你的代码简洁性有很大的改观。数组去重 🐻
正常我们实现数组去重大多都是通过双层遍历或者
indexOf
的方式。双层
for
循环去重利用
indexOf
去重但其实有一种更简单的方式:利用
Array.from
与set
去重这种代码的实现是不是很简洁 😉
数组转化为对象(
Array to Object
)🦑数组转化为对象,大多数同学首先想到的就是这种方法:
但是有一种比较简单快速的方法:
一行代码就能搞定的事情为什么还要用遍历呢?😛
合理利用三元表达式 👩👦👦
有些场景我们需要针对不同的条件,给变量赋予不同的值,我们往往会采用下面这种方式:
但是为什么不采用三元表达式呢?
这种也就是所谓的
Single line
(单行)思想,其实就是代码趋向于简洁性
。转换为数字类型(
Convert to Number
)🔢这种是很常见的,大家用的比较多的可能是
parseInt()
、Number()
这种:其实也可以通过
+
来实现转换:转换为字符串类型(
Convert to String
)🔡转换为字符串一般会用
toString()
、String()
实现:但也可以通过
value + ""
这种来实现:性能追踪 🥇
如果你想测试一段
js
代码的执行耗时,那么你可以尝试下performance
:合并对象(
Combining Objects
)🌊两个对象合并大家用的比较多的可能就是
Object.assign
了:其实有一种更简洁的方式:
也就是通过
展开操作符(spread operator)
来实现。短路运算(
Short-circuit evaluation
) 🥅我们可以通过
&&
或||
来简化我们的代码,比如:数组扁平化(
Flattening an array
)🍓数组的扁平化,我们一般会用
递归
或reduce
去实现递归
reduce
但是
es6
提供了一个新方法flat(depth)
,参数depth
,代表展开嵌套数组的深度,默认是1
求幂运算 🍜
平时我们实现指数运算,用的比较多的应该是
Math.pow()
,比如求2^10
:在
ES7
中引入了指数运算符**
,**
具有与Math.pow()
一样的计算结果。浮点数转为整数(
Float to Integer
)🦊我们一般将浮点数转化为整数会用到
Math.floor()
、Math.ceil()
、Math.round()
。但其实有一个更快的方式:也就是使用
~
,>>
,<<
,>>>
,|
这些位运算符来实现取整截断数组
获取数组中的最后一项 🦁
通常,获取数组最后一项,我们用的比较多的是:
但我们也可以通过
slice
操作来实现:美化你的
JSON
💄日常开发中,我们会经常用到
JSON.stringify
,但大家可能并不大清楚他具体有哪些参数。他有三个参数:
json
: 必须,可以是数组或Object
replacer
: 可选值,可以是数组,也可以是方法space
: 用什么来进行分隔而我们恰恰可以指定第三个参数
space
的值去美化我们的JSON
:Object.create(null)
🐶proto
:新创建对象的原型对象propertiesObject
:可选。要添加到新对象的可枚举(新添加的属性是其自身的属性,而不是其原型链上的属性)的属性。我们对比分别通过
Object.create(null)
和{}
创建对象的不同:从上图可以看到,通过
{}
创建的对象继承了Object
自身的方法,如hasOwnProperty
、toString
等,在新对象上可以直接使用。而使用
Object.create(null)
创建的对象,除了自身属性a
之外,原型链上没有任何属性。也就是我们可以通过
Object.create(null)
这种方式创建一个纯净
的对象,我们可以自己定义hasOwnProperty
、toString
等方法,完全不必担心会将原型链上的同名方法覆盖掉。拷贝数组 🐿
日常开发中,数组的拷贝是一个会经常遇到的场景。其实实现数组的拷贝有很多骚技巧。
Array.slice
展开操作符
使用
Array
构造函数和展开操作符Array.concat
避免多条件并列 🦀
开发中有时会遇到多个条件,执行相同的语句,也就是多个
||
这种:这种写法语义性、可读性都不太好。可以通过
switch case
或includes
这种进行改造。switch case
includes
Object.freeze()
🃏正是由于这种特性,所以在实际项目中,他有很多的适用场景。
像一些纯展示类的页面,可能存在巨大的数组或对象,如果这些数据不会发生更改,那么你就可以使用
Object.freeze()
将他们冻结,这样Vue
就不会对这些对象做setter
或getter
的转换,可以大大的提升性能。The text was updated successfully, but these errors were encountered: