A - C 系列
1、+ 号的隐式类型转换使用
+ [ 3 ]
+ [ 1 , 2 , 3 ] . slice ( - 1 )
2、日期的转换
const addDaysToDate = ( date, n ) => {
const d = new Date ( date) ;
d. setDate ( d. getDate ( ) + n) ;
return d. toISOString ( ) . split ( 'T' ) [ 0 ] ;
} ;
addDaysToDate ( '2020-10-15' , 10 ) ;
平时做日期的计算可能更多的使用时间戳,秒数去加减,其实有对应的 setDate,getDate等方法去做(月份也一样) toISOString 可以将日期对象转换为 YYYY-MM-DDTHH:mm:ss.sssZ 格式,分割掉 T 字符,即可以得到日期形式
3、对象的合并
Object. assign
const addStyles = ( el, styles ) => Object. assign ( el. style, styles)
addStyles ( document. getElementById ( 'my-element' ) , {
background: 'red' ,
color: '#ffff00' ,
fontSize: '3rem'
} )
4、Array.from
let a = Array. from ( { length: 10 } , ( _, i ) => i)
a
5、关于工具函数封装tips
在封装工具类函数时,可以往闭包的角度靠(内部再返回一个函数) 有时候可以具有更好的拓展性
const ary = ( fn, n ) => ( ... arg) => fn ( ... arg. slice ( 0 , n) )
const firstTwoMax = ary ( Math. max, 2 )
firstTwoMax ( 1 , 2 , 3 , 4 )
6、 按条件分割数组
const bifurcateBy = ( arr, fn ) =>
arr. reduce ( ( acc, val, i ) => ( acc[ fn ( val, i) ? 0 : 1 ] . push ( val) , acc) , [
[ ] ,
[ ] ,
] )
bifurcateBy ( [ 'beep' , 'boop' , 'foo' , 'bar' ] , x => x[ 0 ] === 'b' ) ;
7、二分搜索算法,来查找已排序数组中某元素的位置
尽管现在有api可以直接实现位置查找,不过这个算法思想还是可以的
const binarySearch = ( arr, item ) => {
let l = 0 ,
r = arr. length - 1 ;
while ( l <= r) {
const middle = Math. floor ( ( l + r) / 2 )
const guess = arr[ middle]
if ( guess == item) return middle
guess > item ? r = middle - 1 : l = middle + 1
}
return - 1
}
binarySearch ( [ 1 , 2 , 3 , 4 ] , 4 )
二分搜索算法,采取折中的方式,将中间值与目标做比较,然后不断修改中间值,进而找到目标值
8、冒泡排序
const bubbleSort = arr => {
let swapped = false ;
const a = [ ... arr] ;
for ( let i = 1 ; i < a. length; i++ ) {
swapped = false ;
for ( let j = 0 ; j < a. length - i; j++ ) {
if ( a[ j + 1 ] < a[ j] ) {
[ a[ j] , a[ j + 1 ] ] = [ a[ j + 1 ] , a[ j] ] ;
swapped = true ;
}
}
if ( ! swapped) return a;
}
return a;
} ;
核心思想是将当前值a 与 下一位置值b比较,如果 a > b,就把 a和b交互位置 同时,一轮排序其实就可以实现最大值排最后了,所以循环次数越往后会越少,这也是 i < a.length ,j < a.length - i 的原因 es6 的变量交换位置,更加方便了,其实也可以用于多个变量的赋值改变类似: [count, i] = [count + 1, r + 1]…
9、将字符串首字母转换为大写
const capitalize = ( [ first, ... rest] , lowerRest = false ) =>
first. toUpperCase ( ) +
( lowerRest ? rest. join ( '' ) . toLowerCase ( ) : rest. join ( '' ) ) ;
capitalize ( 'fooBar' , true ) ;
10、链式控制异步流程
const chainAsync = fns => {
let curr = 0 ;
const last = fns[ fns. length - 1 ] ;
const next = ( ) => {
const fn = fns[ curr++ ] ;
fn === last ? fn ( ) : fn ( next) ;
} ;
next ( ) ;
} ;
chainAsync ( [
next => {
console. log ( '0 seconds' ) ;
setTimeout ( next, 1000 ) ;
} ,
next => {
console. log ( '1 second' ) ;
setTimeout ( next, 1000 ) ;
} ,
( ) => {
console. log ( '2 second' ) ;
}
] ) ;
异步的实现,其实还是回调的使用,只不过封装后,看似同步 好比 Promise的resolve,获取结果后,通过resolve回调出去 Promise + async ,运用迭代器,使得可以控制函数的暂停和恢复,更加具有同步风范
11、js 实现一个剪切板
const copyToClipboard = str => {
const el = document. createElement ( 'textarea' ) ;
el. value = str;
el. setAttribute ( 'readonly' , '' ) ;
el. style. position = 'absolute' ;
el. style. left = '-9999px' ;
document. body. appendChild ( el) ;
const selected =
document. getSelection ( ) . rangeCount > 0
? document. getSelection ( ) . getRangeAt ( 0 )
: false ;
el. select ( ) ;
document. execCommand ( 'copy' ) ;
document. body. removeChild ( el) ;
if ( selected) {
document. getSelection ( ) . removeAllRanges ( ) ;
document. getSelection ( ) . addRange ( selected) ;
}
}
copyToClipboard ( 'Lorem ipsum' )
12、根据给定函数或者属性,统计符合条件的数组元素的个数
const countBy = ( arr, fn ) =>
arr. map ( typeof fn === 'function' ? fn : val => val[ fn] ) . reduce ( ( acc, val ) => {
acc[ val] = ( acc[ val] || 0 ) + 1 ;
return acc;
} , { } ) ;
countBy ( [ 6.1 , 4.2 , 6.3 ] , Math. floor) ;
countBy ( [ 'one' , 'two' , 'three' ] , 'length' ) ;
countBy ( [ { count: 5 } , { count: 10 } , { count: 5 } ] , x => x. count)
13、实现一个发布订阅模式
const createEventHub = ( ) => ( {
hub: Object. create ( null ) ,
emit ( event, data ) {
( this . hub[ event] || [ ] ) . forEach ( handler => handler ( data) ) ;
} ,
on ( event, handler ) {
if ( ! this . hub[ event] ) this . hub[ event] = [ ] ;
this . hub[ event] . push ( handler) ;
} ,
off ( event, handler ) {
const i = ( this . hub[ event] || [ ] ) . findIndex ( h => h === handler) ;
if ( i > - 1 ) this . hub[ event] . splice ( i, 1 ) ;
if ( this . hub[ event] . length === 0 ) delete this . hub[ event] ;
}
} ) ;
const handler = data => console. log ( data) ;
const hub = createEventHub ( ) ;
let increment = 0 ;
hub. on ( 'message' , handler) ;
hub. on ( 'message' , ( ) => console. log ( 'Message event fired' ) ) ;
hub. on ( 'increment' , ( ) => increment++ ) ;
hub. emit ( 'message' , 'hello world' ) ;
hub. emit ( 'message' , { hello: 'world' } ) ;
hub. emit ( 'increment' ) ;
hub. off ( 'message' , handler) ;
14、补充一点关于函数length属性
function a ( a, b = 10 , c ) { }
a ( 10 , '' , 30 )
a ( 10 , null , 30 )
a ( 10 , undefiend, 30 )