Bit computing
Bitwise operator: operator 1 or between 0
a | b or
任意一个为1结果为1
console.log(0 | 1) //1
console.log(1 | 0) //1
console.log(1 | 1)//1
a&b 与
两个同时为1结果为1
console.log(1 & 1) //1
a ^ b XOR
有且只有一个为1时,结果才为1
console.log(1 ^ 0)//1
console.log(0 ^ 1)//1
~ a non
即0变成1
即1变成0
~1 //0
~0 //1
a >> b right
将运算数的二进制整体右移指定位数,整数高位用0补齐,附属高数用1补齐
10/2 //5
10>>1 //5
a << 1 left
10*2 //20
10<<2 //20
~~ n negated
~~n 来替代Math.floor(n)或者parseInt(n,10)
n|n n&n ~~n 的作用相同
Convert positive numbers to binary
let numbers=5
numbers.toString(2)
Two exchange number may^=
a,b
a^=b
b^=a
a^=b
With a string of logic operations
console.log('a'&&'b'&&'c') // 'c'
console.log('a' && 'b' || 'c') // 'b'
call and apply this point and bind other changes
let a = [1, 2, 3]
let b = [4, 5, 6];
let c = {}
[].push.apply(a, b)
console.log(a)
//[ 1, 2, 3, 4, 5, 6 ]
[].push.apply(c,b)
console.log(c)
//{ '0': 4, '1': 5, '2': 6, length: 3 } 类数组
[].push.call(a, ...b)
console.log(a)
//[ 1, 2, 3, 4, 5, 6 ]
[].push.call(c,...b)
console.log(c)
//{ '0': 4, '1': 5, '2': 6, length: 3 }
bind()也是改变this的指向,但是返回的是一个函数
但是如果用this就别用箭头函数了
function add(c, d) {
return this.a + this.b + c + d;
}
const o = {a: 1, b: 3}
console.log(add.call(o, 5, 7)) //16
console.log(add.apply(o, [10, 20])) //34
console.log(add.bind(o, 5, 7)())//16
ES10
let arr=[1,2,3,[4,5,6,[7,8,9,[1,2,3]]]]
console.log(arr.flat(1))
//[1, 2, 3, 4, 5, 6, Array(4)]
console.log(arr.flat(Infinity))
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
const map = new Map([['a', 1], ['b', 2]]);
Object.fromEntries(map); // => { a: 1, b: 2 }
copyWithin() 浅复制数组的一部分到同一数组的另一个位置,不会改变数组的长度
参数
target(必需):从该位置开始替换数据
start(可选):
end(可选)
console.log([1, 2, 3, 4, 5,6,7].copyWithin(0, 3, 5))
//0 是目标元素0的位置
//[3,5] 包左不包右 ,替换到0位置
//因为不改变数组的长度,所有只替换前面两位[4,5,3,4,5,6,7]
let numbers = [1, 2, 3, 4, 5];
numbers.copyWithin(-2);//[1,2,3,1,2]
numbers.copyWithin(-2, -3, -1);
//// [1, 2, 3, 3, 4] [-3,-1]
// console.log([1, 2, 3, 4, 5].slice(-3, -1)) //3,4
[1, 2, 3, 4, 5].copyWithin(0, 3); // => [4, 5, 3, 4, 5]
flatMap()
console.log([{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}].flatMap(it => [it.a, it.b]))
// => [1, 2, 3, 4, 5, 6]
core.js the interesting codes
let object = {
[Symbol.toStringTag]: 'Foo'
};
'' + object; // => '[object Foo]'
Object.keys('qwe'); // => ['0', '1', '2']
for (let [key, value] of Object.entries({ a: 1, b: 2, c: 3 })) {
console.log(key); // => 'a', 'b', 'c'
console.log(value); // => 1, 2, 3
}
let objects={a:1}
Object.defineProperty(objects,'b',{value:2})
objects[Symbol('c')]=3;
console.log(Object.keys(objects))
//['a']
console.log(Reflect.ownKeys(objects))
//[ 'a', 'b', Symbol(c) ]
**map**
let array = [1];
let map = new Map([['a', 1], [42, 2]]);
map.set(array, 3).set(true, 4);
console.log(map.size); // => 4
console.log(map.has(array)); // => true
console.log(map.has([1])); // => false
console.log(map.get(array)); // => 3
map.forEach((val, key) => {
console.log(val); // => 1, 2, 3, 4
console.log(key); // => 'a', 42, [1], true
});
map.delete(array);
console.log(map.size); // => 3
console.log(map.get(array)); // => undefined
console.log(Array.from(map)); // => [['a', 1], [42, 2], [true, 4]]
let map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (let [key, value] of map) {
console.log(key); // => 'a', 'b', 'c'
console.log(value); // => 1, 2, 3
}
for (let value of map.values()) console.log(value); // => 1, 2, 3
for (let key of map.keys()) console.log(key); // => 'a', 'b', 'c'
for (let [key, value] of map.entries()) {
console.log(key); // => 'a', 'b', 'c'
console.log(value); // => 1, 2, 3
}
map的forEach的第一个参数val第二个参数key
Conversion between hex
let a=10
//十进制转成二进制
console.log(a.toString(2))
//1010
//十进制转成8进制
console.log(a.toString(8))
//12
//十进制转成16进制
let b=20;
console.log(b.toString(16))
//14
console.log(parseInt('1010', 2))
console.log(Number('0b1010'))//二进制转成十进制
0b 二进制 0o 八进制 0x 十六进制
Promise
const sleepRandom=trim=>{
return new Promise(res=>res(trim))
}
sleepRandom(23).then(res=>{
console.log(res)
})
Promise.all(['foo',sleepRandom(23),sleepRandom(43)]).then(res=>{
console.log(res)
//[ 'foo', 23, 43 ]
})
Promise.race()
If the iteration and contains one or more non-commitment or commitment value / resolved / rejected,
Promise.race
resolves a value for the first iteration finds.
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.race(resolvedPromisesArray);
p.then(res=>{
console.log(res) //33
})
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "two");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "two"
// 两个都完成,但 p2 更快
});
RXjs
Asynchronous data flow programming
Observable
Future value or set of events that can be called
Subscription
Mainly for the implementation of the Observable canceled
Operators
Functional programming style using pure function所有的操作符在pipe管道中执行 let foo=new Observable(observable=>{ observable.next(23) }); foo.subscribe(x=>{ console.log(x) }); import {Observable,fromEvent} from 'rxjs'; const button = document.querySelector('.button') fromEvent(button,'click').subscribe(res=>{ console.log(1) }) //多值推送 const observale=new Observable(observable=>{ observable.next('hi'); observable.next('woshi'); observable.next('hello world'); observable.complete(); }); observale.subscribe({ next:value=>{ console.log(value) }, error:err=>{ console.log(err) }, complete:()=>{ console.log('done!') } })
map
import { interval } from 'rxjs'; import { mapTo } from 'rxjs/operators'; from([1,2,3,4]).pipe(map(val=>val+10)).subscribe(res=>{ console.log(res) //1,2,3,4 }) from([ { name: 'Joe', age: 30 }, { name: 'Frank', age: 20 }, { name: 'Ryan', age: 50 } ]).pipe(map(({name})=>name)).subscribe(res=>{ console.log(res) /*Joe Frank Ryan*/ })
Source of the clients of the road
let i=-1
!~i //true
!!~-1 //false
清楚字符串的空格
replace(/^\s+|\s+/g, '')
is.js source
Object.prototype.toString.call()
arguments 带入的结果为 '[object Arguments]'
类数组转成数组
Object.prototype.slice.call()
判断arguments
is.arguments = function(value) { // fallback check is for IE
return toString.call(value) === '[object Arguments]' ||
(value != null && typeof value === 'object' && 'callee' in value);
};
arguments里面有'callee'属性
判断undefined
console.log(undefined == void 0)
判断是不是对象
let a={name:'sss'}
console.log(Object(a) === a)
判断 对象,数组,string是否为空
const empty = function (value) {
if (Object(value)===value) {
var length = Reflect.ownKeys(value).length;
//length==0判断的是空对象
//属性length=1&&Array.isArray()判断数组
//length==2&&... 判断arguments
if (length === 0 || (length === 1 && Array.isArray(value)) ||
(length === 2 && Object.prototype.toString.call(value) === '[object Arguments]')) {
return true;
}
return false;
}
//判断是string
return value === '';
};
const endWith = (str, target) => {
if (typeof str !== 'string') {
return false
}
target += '';
let diff = str.length - target.length
return diff >= 0 && str.indexOf(target, diff) === diff;
}
console.log(endWith('abcder', 'er'))//true
const startWith = (str, target) => {
return typeof str === 'string' && str.indexOf(target) === 0
}
const comparator = {
'<': (a, b) => a < b,
'<=': (a, b) => a <= b,
'>': (a, b) => a > b,
'>=': (a, b) => a >= b
}
const sorted = (array, sign = '<') => {
if (!Array.isArray(array)) {
return false
}
let fn = comparator[sign]
for (let i = 1; i < array.length; i++) {
if (!fn(array[i - 1], array[i])) {
return false
}
}
return true
}
console.log(sorted([1, 2, 3, 3,4],'<='))
matter.js
2D physics engine
Effective number of triangles 611
const triangleNumber = nums => {
nums.sort((a, b) => a - b)
let result = 0
for (let i = nums.length - 1; i >= 2; i--) {
let l = 0
let r = i - 1
while (l < r) {
if (nums[l] + nums[r] > nums[i]) {
result += r - l
r--
} else {
l++
}
}
}
return result
}
Moment.js source
今天是这一年的第几天
Math.floor(
(new Date() - new Date(new Date().getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24
)
getFullYear() 获取年份
console.log(new Date().toISOString())
//2019-08-13T02:44:08.020Z
getDay() //星期几 日-六(0-6)
let full=new Date().getFullYear()
let month=new Date().getMonth()+1
//今天是多少号 getDate()
console.log(new Date().getDate())
//这个月有多少天
let day=new Date(full,month,0).getDate()
算一个数组中最小的那个日期
const array = [
new Date(2017, 4, 13),
new Date(2018, 2, 12),
new Date(2016, 0, 10),
new Date(2016, 0, 9),
];
new Date(Math.min.apply(null, array)).toISOString();
// => "2016-01-08T13:00:00.000Z"
当前时间加上一个星期
let day=new Date().getDate()+7
//设置多少号
console.log(new Date(new Date().setDate(day)))
//2019-08-20T03:14:45.883Z
//另一种方法
console.log(new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 7))
判断两个时间的大小
console.log(new Date(2010, 10, 20) < new Date(2010, 10, 21))
Native Skills
H5 tag
<time> 标签定义日期或时间,或者两者。
<p>
我们在每天早上 <time>9:00</time> 开始营业。
</p>
<p>
我在 <time datetime="2008-02-14">情人节</time> 有个约会。
</p>
width:calc(100%-(100px*2))
font-size: calc(100vw / 30);
:nth-child(odd)好于 :nth-child(2n+1)
odd 奇数 even 偶数
css我已经忘得差不多啦
transition 过渡, transfrom:translateX(100px) 移动
I found a magic skill
如果是求值,就可以用reduce,进行迭代函数求值
const plus1 = a => a + 1;
const mult2 = a => a * 2;
const pipe = (...args) => val => args.reduce((a, b) => b(a), val)
console.log(pipe(plus1,mult2)(10))
//22
Packet
const consecutive = (arr, num) => {
let acc = [];
for (let i = 0; i < arr.length; i++) {
for (let j = arr.length - 1; j >= 1 && i !== j; j--) {
if (arr.slice(i, j).length == num) {
acc.push(arr.slice(i, j))
}
}
}
return acc
}
console.log(consecutive([1, 2, 3, 4, 5, 6], 1))
//[ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ] ]
Object changed url
let obj = {
foo: 1,
bar: 2
};
const joins = (obj, str) =>
Object.keys(obj)
.reduce((acc, val) => acc.concat(val + '=' + obj[val]), [])
.join(str);
console.log(joins(obj, '&'))
//foo=1&bar=2
Judgment is not an object
const isObject=obj=>obj&&obj.constructor===Object;
//判断对象或函数
const isObjFn=obj=>(/function|object/).test(typeof obj)&&obj!=null
const isObject=data=>typeof data==='object'&&
!Array.isArray(data)&&data!==null;
const isEqual = (a, b) => a === b || (a !== a && b !== b)
// console.log(isEqual(NaN, NaN)) //true
Nuggets excellent article
https://github.com/zenghongtu/Blog/issues/1
33-js-concepts
https://github.com/stephentian/33-js-concepts
Wonderful js jsfuck
https://github.com/aemkei/jsfuck/blob/master/jsfuck.js
查看原始包装的函数
0['constructor'] //[Function: Number]
""['constructor'] //[Function: String]
console.log(''.constructor) //[Function: String]
使用+[] 将他们转换成字符串
console.log(''.constructor+[])
//function String() { [native code] }
console.log([].find ['constructor'])
//[Function: Function]
Array.from
const crossJoin = (a, b) => Array.from({ length: a.length }, (v, i) => [a[i], b[i]]);
const crossJoin = (a, b) => Array.from(a, (v, i) => [v, b[i]]);
console.log(crossJoin(['a', 'b', 'c'], ['g', 'd', 'h']))
//[ [ 'a', 'g' ], [ 'b', 'd' ], [ 'c', 'h' ] ]
leetCode 896 monotone sequence
Monotonically increasing or monotonically decreasing returns true, false otherwise
const monotonous = items => { if (items.length <= 1) { return true } let n = items.length - 1 if (items[0] < items[n]) { //升序 for (let i = 1; i <= n; i++) { if (items[i - 1] > items[i]) { return false } } }else{ //降序 for (let i = 0; i <=n ; i++) { if (items[i - 1] < items[i]) { return false } } } return true } //精简版 const monotonous = items => { if (items.length <= 1) { return true } let a = 0, b = 0; for (let i = 1; i < items.length; i++) { a += items[i - 1] < items[i]; b += items[i - 1] > items[i]; } return !(a && b); }
timeage.js source code analysis (a few minutes ago, the first few seconds)
自执行函数
let sum=(i=>i*2)((i=>i+2)(1))
console.log(sum)
//1=>i+2=>i*2 =>(1+2)*3=6
//参数:一个是开始的时间,一个是之后的时间
var format = function format(date, nowDate) {
//计算前后的时间差,精确到s
const sec = diffSec(date, nowDate)
return formatDiff(sec, zh_CN);
};
var diffSec = function diffSec(date, nowDate) {
//如果没有设置后面的时间,就是当前时间
nowDate = nowDate ? toDate(nowDate) : new Date();
return (nowDate - toDate(date)) / 1000;
};
//取年份 new Date('2019')
var toInt = function toInt(f) {
return parseInt(f);
};
//时间转化
var toDate = function toDate(input) {
if (input instanceof Date) return input;
//如果全部是数字,就取年份
if (!isNaN(input) || /^\d+$/.test(input)) return new Date(toInt(input));
input = (input || '').trim()
.replace(/\.\d+/, '') // remove milliseconds
.replace(/-/, '/')
.replace(/-/, '/')
.replace(/(\d)T(\d)/, '$1 $2')
.replace(/Z/, ' UTC') // 2017-2-5T3:57:52Z -> 2017-2-5 3:57:52UTC
.replace(/([\+\-]\d\d)\:?(\d\d)/, ' $1$2'); // -04:00 -> -0400
return new Date(input);
};
console.log(toDate('2019.12.12 12:12:12'))
//2019-12-01T04:12:12.000Z
console.log(toInt('2019.12.12 12:12:12'))
//2019
console.log(new Date('2019'))
//2019-01-01T00:00:00.000Z
//第一个参数是时间差,第二个参数是函数(计算几s前)
function formatDiff(diff, localeFunc) {
var i = 0,
agoin = diff < 0 ? 1 : 0,
// timein or timeago
total_sec = diff = Math.abs(diff);
//计算时间
for (; diff >= SEC_ARRAY[i] && i < SEC_ARRAY.length; i++) {
diff /= SEC_ARRAY[i];
}
diff = toInt(diff);
i *= 2;
if (diff > (i === 0 ? 9 : 1)) i += 1;
return localeFunc(diff, i, total_sec)[agoin].replace('%s', diff);
}
var ZH = '秒_分钟_小时_天_周_个月_年'.split('_');
var SEC_ARRAY = [60, 60, 24, 7, 365 / 7 / 12, 12];
//组成 %s 秒前的大数组
function zh_CN(number, index) {
if (index === 0) return ['刚刚', '片刻后'];
var unit = ZH[parseInt(index / 2)];
return [`${number}${unit}前`, `${number}${unit}后`];
};
console.log(format('2019-08-15', '2019-08-13'))