github 白嫖记(一)

位运算

按位操作符:0或者1之间的运算

a|b

任意一个为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 异或

有且只有一个为1时,结果才为1
console.log(1 ^ 0)//1
console.log(0 ^ 1)//1

~a

即0变成1
即1变成0
~1  //0
~0 //1

a>>b 右移

将运算数的二进制整体右移指定位数,整数高位用0补齐,附属高数用1补齐
10/2    //5
10>>1   //5

a<<1 左移

10*2    //20
10<<2    //20

~~n 取反

~~n    来替代Math.floor(n)或者parseInt(n,10)
n|n   n&n    ~~n  的作用相同

将正数转换为二进制

let numbers=5
numbers.toString(2)

交换两个数可以用^=

a,b
a^=b
b^=a
a^=b

带有string 的逻辑操作

console.log('a'&&'b'&&'c')  // 'c'
console.log('a' && 'b' || 'c') // 'b'

call和apply和bind等改变this指向

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中有意思的代码

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

进制之间的转化

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()

如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则Promise.race 将解析为迭代中找到的第一个值。

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

网址

异步数据流编程

Observable 一个可调用的未来值或事件的集合

Subscription 主要用于取消 Observable的执行

Operators 采用函数式编程风格的纯函数

所有的操作符在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*/
        })

嫖客的源码之路

let i=-1
!~i    //true
!!~-1  //false
清楚字符串的空格
replace(/^\s+|\s+/g, '')

is.js 源码

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物理引擎

http://brm.io/matter-js/

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源码

今天是这一年的第几天
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))

原生技巧

H5标签

<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)   移动

发现一个神奇的技能

如果是求值,就可以用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

分组

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 ] ]

对象改成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

判断是不是对象

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

掘金的优秀文章

https://github.com/zenghongtu/Blog/issues/1

33-js-concepts

https://github.com/stephentian/33-js-concepts

奇妙的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 单调数列

单调递增或者单调递减返回true,否则返回false

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源码分析(几分钟前,几秒前)

自执行函数
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'))

猜你喜欢

转载自www.cnblogs.com/fangdongdemao/p/11359406.html