1.通过 config 命令
.1 npm config set registry https://registry.npm.taobao.org
// yarn config set registry http://registry.npm.taobao.org/
.2 npm info underscore
#(如果上面配置正确, 2 会有字符串response)
2.命令行指定
npm --registry https://registry.npm.taobao.org info underscore
3.编辑 ~/.npmrc 加入下面内容
registry = https://registry.npm.taobao.org
4.npm private proxy registry,
verdaccio
https://github.com/verdaccio/verdaccio
4. 建立或使用镜像,参考: https://github.com/cnpm/cnpmjs.org
npm install --save-dev chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
<span data-bind="text: ko.toJSON(object)"></span>
<!-- ko text: ko.toJSON($data) --><!-- /ko -->
<!-- ko text: ko.toJSON($data, null, 2) --><!-- /ko -->
<span data-bind="text: ko.toJSON(object)"></span>
<pre data-bind="text: ko.toJSON(object, null, 2)"></pre>
# windows下查看端口:
netstat -ano | findstr 8080
# install `node-saas`
npm install --save node-sass --registry=https://registry.npm.taobao.org
8. Coding Fonts: monaspace
, JetBrains Mono
, Fira Code
, Monaco
, Cascadia
, VictorMono
var b = String.raw`C:\Funds-Backend\UploadFiles\PaymentApply\94524f3b-7e32-4349-942f-88d8393b4035.png`.split('\\');
var c = b.slice(2).join('/');
console.log(c);
input[type='number'] {
-moz-appearance:textfield;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
this.item = Object.freeze(Object.assign({}, this.item, changedFields))
function sum() {
var s = Array.prototype.reduce.call(arguments, function (x, y) { return x + y; }, 0);
var f = function () {
var a = Array.prototype.slice.call(arguments);
a.push(s);
return sum.apply(null, a);
};
f.valueOf = function () { return s; };
return f;
}
sum(1,2,3,4);
sum(1)(2)(3);
sum(1,2)(3);
// Ex 1:
let countDownFrom = (num) => {
if (num === 0) return
console.log(num)
countDownFrom(num -1)
};
countDownFrom(10);
// Ex 2:
let categories = [
{ id: 'animals', 'parent': null },
{ id: 'mammals', 'parent': 'animals' },
{ id: 'cats', 'parent': 'mammals' },
{ id: 'dogs', 'parent': 'mammals' },
{ id: 'chihuahua', 'parent': 'dogs' },
{ id: 'labrador', 'parent': 'dogs' },
{ id: 'persian', 'parent': 'cats' },
{ id: 'siamese', 'parent': 'cats' }
]
let makeTree = (categories, parent) => {
let node = {}
categories
.filter(c => c.parent === parent)
.forEach(c => node[c.id] = makeTree(categories, c.id))
return node
}
console.log(
JSON.stringify(
makeTree(categories, null))
, null, 2);
// Ex 3
function getNestedChildren(arr, parent) {
var out = []
for(var i in arr) {
if(arr[i].parent == parent) {
var children = getNestedChildren(arr, arr[i].id)
if(children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
const data = [
{id: 1, title: 'hello', parent: 0},
{id: 2, title: 'hello', parent: 0},
{id: 3, title: 'hello', parent: 1},
{id: 4, title: 'hello', parent: 3},
{id: 5, title: 'hello', parent: 4},
{id: 6, title: 'hello', parent: 4},
{id: 7, title: 'hello', parent: 3},
{id: 8, title: 'hello', parent: 2}
];
getNestedChildren(data, 0);
// get node from tree
function search (tree, value, key = 'id', reverse = false) {
const stack = [ tree[0] ]
while (stack.length) {
const node = stack[reverse ? 'pop' : 'shift']()
if (node[key] === value) return node
node.children && stack.push(...node.children)
}
return null
}
search(data, 'randomNode_2', 'title')
// Other methods make tree
function toTree (items, rootId = null, idAlias = 'id', parentIdAlias = 'parentId') {
return items.filter(item => item[parentIdAlias] === rootId)
.map(item => ({
...item,
children: toTree(items, item[idAlias], idAlias, parentIdAlias)
}))
}
function toTree2 (items = [], rootId = null, idAlias = 'id', parentIdAlias = 'parentId') {
const output = []
for (const i in items) {
if (item[i][parentIdAlias] === rootId) {
const children = toTree2(items, items[i][idAlias], idAlias, parentIdAlias)
if (children.length) {
items[i].children = children
}
output.push(items[i])
}
}
}
function toTree3 (items = [], rootId = null, idAlias = 'id', parentIdAlias = 'parentId' ) {
const idMapping = items.reduce((acc, el, i) => {
acc[el[idAlias]] = i
return acc
}, {})
let root
items.forEach(el => {
if (el[idAlias] === rootId) {
root = el
return
}
const parentEl = items[idMapping[el[parentIdAlias]]]
parentEl.children = [...(parentEl.children) || [], el]
})
return [root]
}
Test Performance: items.length =
12137
>toTree
:40276ms
>toTree2
:21210ms
>toTree3
:129ms
<p data-height="265" data-theme-id="0" data-slug-hash="deyOEB" data-default-tab="js,result" data-user="ellipse" data-embed-version="2" data-pen-title="deyOEB" class="codepen">See the Pen <a href="https://codepen.io/ellipse/pen/deyOEB/">deyOEB</a> by Lusai (<a href="https://codepen.io/ellipse">@ellipse</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
// 1 fail with iframe
obj instanceof Array
// 2 fail with iframe
obj.constructor === Array
// 3 rely on Object.prototype.toString and call method
Object.prototype.toString.call(obj) === '[object Array]'
// 4 ES5 the best
if (Array.isArray) {
return Array.isArray(v);
}
//Polyfill
if(!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
}
// 5 the fatest way and all browsers supported
function isArray(value){
return value && typeof value === 'object' && value.constructor === Array;
}
function isString(value) {
return typeof value === 'string' || value instanceof String;
}
function isFunction (value) {
return typeof value === 'function';
}
function isNull (value) {
return value === null;
}
function isUndefined (value) {
return typeof value === 'undefined';
}
function isBoolean (value) {
return typeof value === 'boolean';
}
function isRegExp (value) {
return value && typeof value === 'object' && value.constructor === RegExp;
}
function isError (value) {
return value instanceof Error && typeof value.message !== 'undefined';
}
function isDate (value) {
return value instanceof Date;
}
function isSymbol (value) {
return typeof value === 'symbol';
}
function isError (value) {
return value instanceof Error && typeof value.message !== 'undefined';
}
for example, in Vuejs
// declare the cancel function
let cancel
export default {
methods: {
query() {
axios.get(`${url}`, {
params: {},
cancelToken: new axios.CancelToken(function (c) {
cancel = c
})
})
.then(response => {
// ...
})
.catch(error => {
// catch the `cancel` message
if (axios.isCancel(error)) {
console.log(error)
alert('xxx')
} else {
console.log(error)
}
})
},
someFunc () {
// call the `cancel` function
cancel('you have cancel the request')
}
}
}
//without indexof...
let uniqueWithoutArrayMethod = (arr) => {
let res = [arr[0]]
for (let i = 1; i < arr.length; i++) {
let repeat = false
for (let j = 0; j < res.length; j++) {
if (arr[i] === res[j]) {
repeat = true
break
}
}
if (!repeat) {
res.push(arr[i])
}
}
return res
}
console.log(uniqueWithoutArrayMethod([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, 3]))
// with another array
let uniqueWithAnotherArray = (arr) => {
let result = []
let len = arr.length
for (let i = 0; i < len; i++) {
// if (result.indexOf(arr[i]) < 0) {
if (!result.includes(arr[i])) {
result.push(arr[i])
}
}
return result
}
console.log(uniqueWithAnotherArray([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, 3]))
//with Object
let uniqueWithOject = (arr) => {
let obj = {}
arr.map((a) => (obj[a] = a))
let result = Object.values(obj)
return result
}
console.log(uniqueWithOject([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, 3]))
//with set
let uniqueWithSet = (arr) => {
let arr3 = [...new Set(arr)]
let arr5 = Array.from(new Set(arr))
return arr3
}
console.log(uniqueWithSet([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, 3]))
//deduplication on self,change origin array
let uniqueOnSelf = (arr) => {
let len = arr.length
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[j] === arr[i]) {
arr.splice(j, 1)
j--
len--
}
}
}
return arr
}
console.log(uniqueOnSelf([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, 3]))
Number.prototype.toCurrencyString = function(prefix, suffix) {
if (typeof prefix === 'undefined') { prefix = '$'; }
if (typeof suffix === 'undefined') { suffix = ''; }
var _localeBug = new RegExp((1).toLocaleString().replace(/^1/, '').replace(/\./, '\\.') + "$");
return prefix + (~~this).toLocaleString().replace(_localeBug, '') + (this % 1).toFixed(2).toLocaleString().replace(/^[+-]?0+/,'') + suffix;
}
var MyNumber = 123456789.125;
console.log(MyNumber.toCurrencyString());
function customizer(objValue, srcValue) {
if (_.isArray(objValue)) {
if (objValue[0] !== srcValue[0]) {
return objValue.concat(srcValue)
} else {
return objValue
}
}
}
var object = { a: [1], b: [2] }
var other = { a: [1], b: [4] }
// output: {a: [1], b: [2, 4]}
_.mergeWith(object, other, customizer)
33. Abort fetch
request. AbortController
<div>
<button class="download">fetch</button>
<button class="abort">cancel fetch</button>
</div>
//ex
var controller = new AbortController()
var signal = controller.signal
var downloadBtn = document.querySelector('.download')
var abortBtn = document.querySelector('.abort')
downloadBtn.addEventListener('click', fetchData)
abortBtn.addEventListener('click', function () {
controller.abort()
console.log('fetch data cancel or aborted...')
})
function fetchData() {
fetch('https://api.github.com/users/dddd', { signal })
.then(function (response) {
console.log(response)
})
.catch(function (e) {
console.log('get data error: ' + e.message)
})
}
Note: When
abort()
is called, thefetch()
promise rejects with anAbortError
34. 生成器函数可以用 GeneratorFunction
或 function* expression
定义。Link
生成器在执行时能暂停,后面又可以从暂停出继续执行。调用一个生成器函数不会立刻执行里面的语句,而是返回一个这个生成器的迭代器(iterator)对象。当这个迭代器的
next()
被首次调用时,其内语句会执行到yield
的位置为止,yield
后紧跟迭代器要返回的值。或者如果用的是yield*
,则表示讲执行权移交给另外一个生成器函数,当前的生成器暂停执行。next()
方法返回一个对象{value: '', done: ''}
,value
为本次yield
表达式的返回值,done
属性为布尔类型,表示生成器后续是否还有yield
语句,即生成器函数是否已经执行完毕并返回。调用next()
方法时,如果传入了参数,name 这个参数会作为上一条执行的yield
语句的返回值。
/* Generator */
function* iterArray(arr) {
if (Array.isArray(arr)) {
for (let i = 0; i < arr.length; i++) {
yield* iterArray(arr[i])
}
} else {
yield arr
}
}
// for-of
var arr = ['a', ['b', 'c'], ['d', 'e', 'f']]
for (var x of iterArray(arr)) {
console.log(x)
}
// 迭代器展开
var gen = iterArray(arr)
arr = [...gen]
console.log(arr)
35. 怪异模式MDN
36. 可视化库 Blog
37. 导出 csv 参考链接
// Assuming you are using an array of arrays for your data
const rows = [
['name1', 'city1', 'some other info'],
['name2', 'city2', 'more info'],
]
const dataToCsvURI = (data) =>
encodeURI(
`data:text/csv;charset=utf-8,${data
.map((row, index) => row.join(','))
.join(`\n`)}`
)
const link = document.createElement('a')
link.setAttribute('href', dataToCsvURI(rows))
link.setAttribute('download', 'my_data.csv')
link.innerHTML = 'Click Here to download'
document.body.appendChild(link)
link.click()
function downloadableCSV(rows) {
var content = 'data:text/csv;charset=utf-8,';
rows.forEach(function(row, index) {
content += row.join(',') + '\n';
});
return encodeURI(content);
}
var rows = [
['name1', 2, 3],
['name2', 4, 5],
['name3', 6, 7],
['name4', 8, 9],
['name5', 10, 11]
];
$('#download').click(function() {
window.open(downloadableCSV(rows));
});
**Excel打开CSV文件汉字乱码**[参考链接](https://stackoverflow.com/questions/31959487/utf-8-encoidng-issue-when-exporting-csv-file-javascript)
> 问题是编码问题需要使用`utf-8 with BOM`
```js
var blob = new Blob(["\uFEFF"+csv], {
type: 'text/csv; charset=utf-18'
});
```
> 文档带 BOM 编码
> > Excel 打开 CSV 文件,
> > 数据里面含有"1,900.00"这样带`,`的数据会解析错误,解决方法是在数据外面用`'`包起来一层;
> > 数据里面含有"2020-02-16"这样的数据会显示成一堆`#`号,解决方法是在数据前加`\t`
---
## 38 `Reactive programming` [Good Post](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754)
> Reactive programming is programming with asynchronous data streams.
## 39. Download file from server when response is `blob` data
```js
downloadFile (fileName, blob) {
let url = URL.createObjectURL(blob)
let a = document.createElement('a')
a.download = fileName
a.href = url
a.click()
}
downloadFTPFile (params) {
const { fileName, filePath } = { ...params.row }
if (fileName && filePath) {
axios.post(`ftp/download`, null, {
params: {
fileName,
filePath
},
responseType: 'blob' // important!!!
})
.then(res => {
// const disposition = res.request.getResponseHeader(
// "Content-disposition"
// )
// const fileName = decodeURI(disposition.split("filename=")[1])
let resBlob = res.data
// different type, has two methods.
// 1.
let url = window.URL.createObjectURL(new Blob([resBlob], {
'type': 'application/octet-stream'
}))
// 2.
// let url = window.URL.createObjectURL(resBlob)
let a = document.createElement("a")
a.download = fileName
a.href = url
a.click()
this.$Message.success('下载成功')
})
performance
.getEntriesByType('resource')
.map((t) => t.name)
.filter((url) => url.includes('woff'))
.join('\n')
copy()
copy()
copy($_) // $_ 返回最近表达式的值
$_
, Reference
2 + 2
$_
$0
$1
$2
$3
$4
debug()
const url = 'https://api.github.com/search/repositories'
const a = async () => {
const res = await fetch(`${url}?q=workbox`)
const data = await res.json()
const names = data.items.map((item) => item.name)
console.log(names)
}
debug(a)
a()
monitor()
monitor(setTimeout)
setTimeout((_) => console.log('pause'), 500)
console.log('first')
unmonitor(setTimeout)
queryObjects()
class Foo {}
const a = new Foo()
const b = new Foo()
b.prop = 1
queryObjects(Foo)
Eager Evaluation
// in the console
;/[0-9]{3}-[0-9]{3}-[0-9]{4}/.exec('Call us 555-867-5309! Thanks')
Cmd + Shift + P
, inputundo
/right
/undoc
;[...document.querySelectorAll('a')]
.map((e) => e.innerText.trim())
.sort()
.filter(Boolean)
let arr = new Uint32Array(10)
window.crypto.getRandomValues(arr)
43. 内容多单元格显示问题 css, reference
/* styles for '...' */
.block-with-text {
/* hide text if it more than N lines */
overflow: hidden;
/* for set '...' in absolute position */
position: relative;
/* use this value to count block height */
line-height: 1.2em;
/* max-height = line-height (1.2) * lines max number (3) */
max-height: 3.6em;
/* fix problem when last visible word doesn't adjoin right side */
text-align: justify;
/* place for '...' */
margin-right: -1em;
padding-right: 1em;
}
/* create the ... */
.block-with-text:before {
/* points in the end */
content: '...';
/* absolute position */
position: absolute;
/* set position to right bottom corner of block */
right: 0;
bottom: 0;
}
/* hide ... if we have text, which is less than or equal to max lines */
.block-with-text:after {
/* points in the end */
content: '';
/* absolute position */
position: absolute;
/* set position to right bottom corner of text */
right: 0;
/* set width and height */
width: 1em;
height: 1em;
margin-top: 0.2em;
/* bg color = bg color under block */
background: white;
}
44. Object clone
Shallow or Deep. reference
let obj = {
a: 1,
b: {
c: 2,
},
}
let newObj = Object.assign({}, obj)
console.log(newObj) // { a: 1, b: { c: 2} }
obj.a = 10
console.log(obj) // { a: 10, b: { c: 2} }
console.log(newObj) // { a: 1, b: { c: 2} }
newObj.a = 20
console.log(obj) // { a: 10, b: { c: 2} }
console.log(newObj) // { a: 20, b: { c: 2} }
newObj.b.c = 30
console.log(obj) // { a: 10, b: { c: 30} }
console.log(newObj) // { a: 20, b: { c: 30} }
// Note: newObj.b.c = 30; Read why.???.
let someObj = {
a: 2,
}
let obj = Object.create(someObj, {
b: {
value: 2,
},
c: {
value: 3,
enumerable: true,
},
})
let objCopy = Object.assign({}, obj)
console.log(objCopy) // { c: 3 }
45. Rendering Performance Reference
布局是浏览器计算各元素几何信息的过程:元素的大小以及在页面中的位置。 根据所用的 CSS、元素的内容或父级元素,每个元素都将有显式或隐含的大小信息。此过程在 Chrome、Opera、Safari 和 Internet Explorer 中称为布局 (Layout)。 在 Firefox 中称为自动重排 (Reflow),但实际上其过程是一样的。与样式计算相似,布局开销的直接考虑因素如下:1. 需要布局的元素数量。2.这些布局的复杂性。
npm install --save chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
st=>start:开始
e=>end:结束
op=>operation:操作
cond=>condition:确认
st->op->cond
cond(yes)->e
cond(no)->op
Alice->Bob: Hello Bob, how are you?
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!
48 element all width and height (https://msdn.microsoft.com/en-us/library/hh781509(VS.85).aspx)
uname -a
uname -mrs
lsb_release -a
cat /proc/version
cat /etc/issue
tail /etc/redhat-release
<input type="file" id="browse" onchange="previewFiles()" multiple />
<div id="preview"></div>
function previewFiles() {
var preivew = document.querySelector('#preview')
var files = document.querySelector('input[type=file]').files
function readAndPreview(file) {
if (/\.(jpg?g|png|gif)$/i.test(file.name)) {
var reader = new FileReader()
reader.addEventListener(
'load',
function () {
var image = new Image()
image.height = 100
image.title = file.name
image.src = this.result
preivew.appendChild(image)
},
false
)
reader.readAsDataURL(file)
}
}
if (files) {
;[].forEach.call(files, readAndPreview)
}
}
.note-content {
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
color: rgba(0, 0, 0, 0.87);
font-size: 14px;
/*! autoprefixer: off */
-webkit-box-orient: vertical;
/*! autoprefixer: on */
}
export default {
data() {
return {
list: [],
query: {
currentPage: 1,
pageSize: 10,
},
}
},
methods: {
handleSizeChange(val) {
this.query.pageSize = val
this.excelDataPagination()
},
handleCurrentChange(val) {
this.query.currentPage = val
this.excelDataPagination()
},
excelDataPagination() {
let currentPage = this.query.currentPage
let pageSize = this.query.pageSize
--currentPage
this.list = this.all.slice(
currentPage * pageSize,
(currentPage + 1) * pageSize
)
},
},
}
curl URL -o filename --progress
Example:
curl https://unpkg.com/[email protected]/dist/ag-grid-enterprise.min.js -o my-ag-grid
.min.js --progress
Ex: chrome google it
-1 selected the "chrome.exe" etc.
-2 add arguments and insert Macro Param: --new-tab "https://google.com/search?q=$SelectedText$" (--new-window, --incognito, arguments of chrome app)
1 .netStandard, Version=2.0.0.0, Culture=neutral, 的引用问题解决
在csproj文件里面,添加 <Reference Include="netstandard" />
2. 提示如上(12)错误时,打开Rider设置 -> Toolset and Build -> Use MSBUILD version: Latest installed. [Done]
window.console &&
console.log(
'%c\n ********* \n ******* ******* \n *** *** \n ** ** \n ***** ** *** \n **** ***** ** \n ** ** \n * * \n ** ** ** * \n **** ** ** ** ****** \n ** ** ** ** **** \n *** ** *** \n * ** ** \n * **** * \n * * \n** ** \n* ** ** * \n** *********** * \n * *** ** \n ** ** \n *** ** \n **** **** \n **** **** \n ************************************************* \n \n Happy to see you here! We are hiring the sharpest minds in the\n industry who want to build the most sophisticated and delightful\n applications on the web.\n \n Check out https://www.icloud.com/jobs/\n \n',
'font-family: Menlo, monospace'
)
57. Intl format currency
, locale
etc. Intl
Ex:
Vue
currency filter
export default {
filters: {
currency(value) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(value)
},
},
}
Use
<span>{{value | currency}}</span>
other example
console.log(
new Intl.NumberFormat('en-IN', {
style: 'currency',
currency: 'RMB',
minimumFractionDigits: 6,
}).format(12345789.23654)
)
format digit
...
filters: {
currency(value, places) {
return new Intl.NumberFormat("en-US",
{
style: "currency",
currency: "USD",
minimumFractionDigits: places || 2,
maximumFractionDigits: places || 2
}).format(value)
}
}
58. XSS cross site scripting
, where we let someone else run JavaScript on our page.web bos
const first = 'Wes'
const aboutMe = `I love to do evil <img src="http://unsplash.it/100/100?random" onload="alert('you got hacked');" />`
const html = `
<h3>${first}</h3>
<p>${aboutMe}</p>
`
const bio = document.querySelector('img')
bio.innerHTML = html
Solution:
Sanitizing
your HTML. UsingDOMPurify
(https://github.com/cure53/DOMPurify) library.
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify.0.8.2/purify.min.js"></script>
<script>
function sanitize(strings, ...values) {
const dirty = strings.reduce((prev, next, i) => `${prev}${next}${values[i]} || ''}`, '');
return DomPurify.sanitize(dirty);
}
const first = 'Wes';
const aboutMe = sanitize`I love to do evil <img src="http://unsplash.it/100/100?random" onload="alert('you got hacked');" />`;
const html = `
<h3>${first}</h3>
<p>${aboutMe}</p>
`;
const bio = document.querySelector('.bio');
bio.innerHTML = html;
</script>
function group(list, props) {
return list.reduce((a, b) => {
;(a[b[props]] = a[b[props]] || []).push(b)
return a
}, {})
}
How to
var arr = [
{
routerName: "approval",
name: "moduleA",
path: "/approval",
module: "workbench",
systemName: "System1",
systemCode: 2
},
{
routerName: "approval",
name: "moduleB",
path: "/approval",
module: "workbench",
systemName: "System2",
systemCode: 2
},
{
routerName: "approval",
name: 'moduleC',
path: "/approval",
module: "workbench",
systemName: "System1',
systemCode: 2
}
];
console.log(groupBy(arr, 'systemName')
download jsplumbtoolkit.js, find
window.eval(decodeURIComponent("..."))
code.
// 1. exec this code
window._j = ~[]
window._j = {
___: ++window._j,
$$$$: (![] + '')[window._j],
__$: ++window._j,
$_$_: (![] + '')[window._j],
_$_: ++window._j,
$_$$: ({} + '')[window._j],
$$_$: (window._j[window._j] + '')[window._j],
_$$: ++window._j,
$$$_: (!'' + '')[window._j],
$__: ++window._j,
$_$: ++window._j,
$$__: ({} + '')[window._j],
$$_: ++window._j,
$$$: ++window._j,
$___: ++window._j,
$__$: ++window._j,
}
window._j.$_ =
(window._j.$_ = window._j + '')[window._j.$_$] +
(window._j._$ = window._j.$_[window._j.__$]) +
(window._j.$$ = (window._j.$ + '')[window._j.__$]) +
(!window._j + '')[window._j._$$] +
(window._j.__ = window._j.$_[window._j.$$_]) +
(window._j.$ = (!'' + '')[window._j.__$]) +
(window._j._ = (!'' + '')[window._j._$_]) +
window._j.$_[window._j.$_$] +
window._j.__ +
window._j._$ +
window._j.$
window._j.$$ =
window._j.$ +
(!'' + '')[window._j._$$] +
window._j.__ +
window._j._ +
window._j.$ +
window._j.$$
window._j.$ = window._j.___[window._j.$_][window._j.$_]
window._j.$(
window._j.$(
window._j.$$ +
'"' +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.__$ +
window._j.$$$$ +
'(' +
window._j.$$_$ +
window._j._$ +
window._j.$$__ +
window._j._ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$_$ +
window._j.$$$_ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$$_ +
window._j.__ +
'.' +
(![] + '')[window._j._$_] +
window._j._$ +
window._j.$$__ +
window._j.$_$_ +
window._j.__ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.__$ +
window._j._$ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$$_ +
'.\\' +
window._j.__$ +
window._j.$_$ +
window._j.___ +
window._j._$ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$$ +
window._j.__ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$$_ +
window._j.$_$_ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$_$ +
window._j.$$$_ +
"!=='\\" +
window._j.__$ +
window._j.$_$ +
window._j._$_ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$$ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j.___ +
(![] + '')[window._j._$_] +
window._j._ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$_$ +
window._j.$_$$ +
window._j.__ +
window._j._$ +
window._j._$ +
(![] + '')[window._j._$_] +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j._$$ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.__$ +
window._j.__ +
'.' +
window._j.$$__ +
window._j._$ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$_$ +
"')" +
window._j.__ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.___ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$_ +
window._j._$ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j.$$$ +
'\\' +
window._j.$__ +
window._j.___ +
'\\' +
window._j.__$ +
window._j.$_$ +
window._j.$$_ +
window._j.$$$_ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j.$$$ +
'\\' +
window._j.$__ +
window._j.___ +
'\\' +
window._j.__$ +
window._j.___ +
window._j.$_$ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$_ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$_ +
window._j._$ +
'\\' +
window._j.__$ +
window._j.$$_ +
window._j._$_ +
'();' +
'"'
)()
)()
// 2. exec this
_j.$$ +
'"\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
_j.$$$$ +
'\\' +
_j.$__ +
_j.___ +
'(\\' +
_j.__$ +
_j.$_$ +
_j.$$_ +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j.$$$ +
'\\' +
_j.$__ +
_j.___ +
'\\' +
_j.__$ +
_j.___ +
_j.$__ +
_j.$_$_ +
_j.__ +
_j.$$$_ +
'().\\' +
_j.__$ +
_j.$__ +
_j.$$$ +
_j.$$$_ +
_j.__ +
'\\' +
_j.__$ +
_j._$_ +
_j.$__ +
'\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
'\\' +
_j.__$ +
_j.$_$ +
_j.$_$ +
_j.$$$_ +
'()\\' +
_j.$__ +
_j.___ +
'>\\' +
_j.$__ +
_j.___ +
_j.__$ +
_j.$__ +
_j.$$$ +
_j.$___ +
_j.$$_ +
_j.$$_ +
_j.$__ +
_j._$$ +
_j.$$$ +
_j.$_$ +
_j.___ +
_j.$$$ +
_j.__$ +
'){' +
_j.$_$_ +
(!1 + '')[_j._$_] +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
_j.__ +
"('\\" +
_j.__$ +
_j.$_$ +
_j._$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$$ +
'\\' +
_j.__$ +
_j._$_ +
_j.___ +
(!1 + '')[_j._$_] +
_j._ +
'\\' +
_j.__$ +
_j.$_$ +
_j.$_$ +
_j.$_$$ +
'\\' +
_j.$__ +
_j.___ +
'\\' +
_j.__$ +
_j._$_ +
_j.$__ +
_j._$ +
_j._$ +
(!1 + '')[_j._$_] +
'\\' +
_j.__$ +
_j.$_$ +
_j._$$ +
'\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
_j.__ +
'\\' +
_j.$__ +
_j.___ +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j.$$_ +
_j.$_$_ +
(!1 + '')[_j._$_] +
_j._ +
_j.$_$_ +
_j.__ +
'\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
_j._$ +
'\\' +
_j.__$ +
_j.$_$ +
_j.$$_ +
'\\' +
_j.$__ +
_j.___ +
'\\' +
_j.__$ +
_j.$$_ +
_j.___ +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
'\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
_j._$ +
_j.$$_$ +
'\\' +
_j.$__ +
_j.___ +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$$ +
_j.___ +
'\\' +
_j.__$ +
_j.$$_ +
_j.___ +
'\\' +
_j.__$ +
_j.$_$ +
_j.__$ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
_j.$$$_ +
_j.$$_$ +
".');" +
_j.__ +
'\\' +
_j.__$ +
_j.$_$ +
_j.___ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
_j._$ +
'\\' +
_j.__$ +
_j.$$_ +
_j.$$$ +
'\\' +
_j.$__ +
_j.___ +
'\\' +
_j.__$ +
_j.$_$ +
_j.$$_ +
_j.$$$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j.$$$ +
'\\' +
_j.$__ +
_j.___ +
'\\' +
_j.__$ +
_j.___ +
_j.$_$ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
_j._$ +
'\\' +
_j.__$ +
_j.$$_ +
_j._$_ +
'();}"'
then we will get the following code in DevTools console panel.
return "\151f\40(\156e\167\40\104ate().\147et\124\151\155e()\40>\401478664375071){ale\162t('\152\163\120lu\155b\40\124ool\153\151t\40e\166aluat\151o\156\40\160e\162\151od\40e\170\160\151\162ed.');t\150\162o\167\40\156e\167\40\105\162\162o\162();}"
finally,
unescape
it.
unescape(
"\151f\40(\156e\167\40\104ate().\147et\124\151\155e()\40>\401478664375071){ale\162t('\152\163\120lu\155b\40\124ool\153\151t\40e\166aluat\151o\156\40\160e\162\151od\40e\170\160\151\162ed.');t\150\162o\167\40\156e\167\40\105\162\162o\162();}"
)
here we get the following code
if (new Date().getTime() > 1478664375071) {
alert('jsPlumb Toolkit evaluation period expired.')
throw new Error()
}
Enjoy it
history | awk '{print $2}' | sort | uniq -c | sort -rn | head -10
63. CSS hack of IE 😭😭😰😰😰😰😰, hack gist
for example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.color {
color: red;
}
/* IE 8,9 */
@media screen\0 {
.color {
color: aqua;
}
}
/* ie 10, 11 hack */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.color {
color: rebeccapurple;
}
}
_:-ms-fullscreen,
:root .ie11up {
color: blue;
}
</style>
</head>
<body>
<div class="color">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium
neque suscipit ex voluptatem tempora ullam in maiores nesciunt natus,
laboriosam, explicabo dolor commodi eius unde sequi fugiat quis iure
itaque!
</div>
</body>
</html>
function delay(time) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, time)
})
}
delay(100) // step 1
.then(function STEP2() {
console.log('step 2 (after 100ms)')
return delay(200)
})
.then(function STEP3() {
console.log('step 3 (after another 200ms)')
})
.then(function STEP4() {
console.log('step 4 (next Job)')
return delay(50)
})
.then(function STEP5() {
console.log('step 5 (after another 50ms)')
})
function request(url) {
return new Promise(function (resolve, reject) {
ajax(url, resolve)
})
}
var rejectedPr = new Promise(function (resolve, reject) {
// resolve this promise with a rejected promise
resolve(Promise.reject('Oops'))
})
rejectedPr.then(
function fulfilled() {
// never gets here
},
function rejected(err) {
console.log(err) // "Oops"
}
)
function printing() {
console.log(1)
setTimeout(function () {
console.log(2)
}, 1000)
setTimeout(function () {
console.log(3)
}, 0)
console.log(4)
}
// 1 4 3 2
////////////////////
function* g1() {
yield 2
yield 3
yield 4
}
function* g2() {
yield 1
yield* g1()
yield 5
}
var iterator = g2()
console.log(iterator)
////////////////////
// FP
function sum() {
var s = Array.prototype.reduce.call(
arguments,
function (x, y) {
return x + y
},
0
)
var f = function () {
var a = Array.prototype.slice.call(arguments)
a.push(s)
return sum.apply(null, a)
}
f.valueOf = function () {
return s
}
return f
}
sum(1, 2, 3, 4)
sum(1)(2)(3)
sum(1, 2)(3)
//////////////////
// Cloure && EventLoop
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i)
}, 100 * i)
}
//for(var i = 0; i< 10; i++){
// setTimeout((function() {
// console.log(i)
// })(i), 100*i)
//}
// for(let i = 0; i< 10; i++){
// setTimeout(function() {
// console.log(i)
//}, 100*i)
//}
const obj = {
a: 1,
b: 2,
c: 3,
}
let { a, ...newObj } = obj
console.log(newObj)
obj.b = 44
console.log(newObj)
Stage 0: Strawman, Stage 1: Proposal, Stage 2: Draft, Stage 3: Candidate, Stage 4: Finished
Stage 4
: Ready for the specification of the current year.
::selection {
background: #b408d2;
color: #fff;
}
const data = [
['Foo', 'programmer'],
['Bar', 'bus driver'],
['Moo', 'Reindeer Hunter'],
]
function download_csv() {
const csv = 'Name,Title\n'
data.forEach(function (row) {
csv += row.join(',')
csv += '\n'
})
let hiddenElement = document.createElement('a')
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv)
hiddenElement.target = '_blank'
hiddenElement.download = 'people.csv'
hiddenElement.click()
}
**/.~*.xls
**/.~*.doc
**/.~*.ppt
**/.~*.xlsx
**/.~*.docx
**/.~*.pptx
**/~*.xls
**/~*.doc
**/~*.ppt
**/~*.xlsx
**/~*.docx
**/~*.pptx
with form data
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
without form data
doRedirectNSTC () {
const winName = 'MyWindow'
const winURL = 'http://localhost:8085/Account/Redirect'
const windowOption = 'resizable=yes,height=600,width=800,location=0,menubar=0,scrollbars=1'
const params = { 'iv_user': '00095' }
const form = document.createElement('form')
form.setAttribute('method', 'post')
form.setAttribute('action', winURL)
form.setAttribute('target', winName)
for (let i in params) {
if (params.hasOwnProperty(i)) {
let input = document.createElement('input')
input.type = 'hidden'
input.name = i
input.value = params[i]
form.appendChild(input)
}
}
document.body.appendChild(form)
window.open('', winName, windowOption)
form.target = winName
form.submit()
document.body.removeChild(form)
}
function has(browser) {
const ua = navigator.userAgent
if (browser === 'ie') {
const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1
if (isIE) {
const reIE = new RegExp('MSIE (\\d+\\.\\d+);')
reIE.test(ua)
return parseFloat(RegExp['$1'])
} else {
return false
}
} else {
return ua.indexOf(browser) > -1
}
}
const csv = {
_isIE11() {
let iev = 0
const ieold = /MSIE (\d+\.\d+);/.test(navigator.userAgent)
const trident = !!navigator.userAgent.match(/Trident\/7.0/)
const rv = navigator.userAgent.indexOf('rv:11.0')
if (ieold) {
iev = Number(RegExp.$1)
}
if (navigator.appVersion.indexOf('MSIE 10') !== -1) {
iev = 10
}
if (trident && rv !== -1) {
iev = 11
}
return iev === 11
},
_isEdge() {
return /Edge/.test(navigator.userAgent)
},
_getDownloadUrl(text) {
const BOM = '\uFEFF'
// Add BOM to text for open in excel correctly
if (window.Blob && window.URL && window.URL.createObjectURL) {
const csvData = new Blob([BOM + text], { type: 'text/csv' })
return URL.createObjectURL(csvData)
} else {
return (
'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text)
)
}
},
download(filename, text) {
if (has('ie') && has('ie') < 10) {
// has module unable identify ie11 and Edge
const oWin = window.top.open('about:blank', '_blank')
oWin.document.charset = 'utf-8'
oWin.document.write(text)
oWin.document.close()
oWin.document.execCommand('SaveAs', filename)
oWin.close()
} else if (has('ie') === 10 || this._isIE11() || this._isEdge()) {
const BOM = '\uFEFF'
const csvData = new Blob([BOM + text], { type: 'text/csv' })
navigator.msSaveBlob(csvData, filename)
} else {
const link = document.createElement('a')
link.download = filename
link.href = this._getDownloadUrl(text)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
},
}
export default csv
// Ex:
let urls = ['https://api.github.com/users/iliakan', '/', 'http://no-such-url']
Promise.all(urls.map((url) => fetch(url).catch((err) => err)))
.then((responses) =>
Promise.all(
// if it's an error then pass on
// otherwise response.json() and catch errors as results
responses.map((r) =>
r instanceof Error ? r : r.json().catch((err) => err)
)
)
)
.then((results) => {
alert(results[0].name) // Ilya Kantor
alert(results[1]) // SyntaxError: Unexpected token < in JSON at position 0
alert(results[2]) // TypeError: failed to fetch (text may vary)
})
const transformRequestOptions = params => {
let options = ''
for (const key in params) {
if (typeof params[key] !== 'object' && params[key]) {
options += `${key}=${params[key]}&`
} else if (typeof params[key] === 'object' && params[key] && params[key].length) {
params[key].forEach(el => {
options += `${key}=${el}&`
})
}
}
return options ? options.slice(0, -1) : options;
}
// improved
const parseParams = (params) => {
const keys = Object.keys(params)
let options = ''
keys.forEach((key) => {
const isParamTypeObject = typeof params[key] === 'object'
const isParamTypeArray = isParamTypeObject && (params[key].length >= 0)
if (!isParamTypeObject) {
options += `${key}=${params[key]}&`
}
if (isParamTypeObject && isParamTypeArray) {
params[key].forEach((element) => {
options += `${key}=${element}&`
})
}
})
return options ? options.slice(0, -1) : options
}
// how to use, Ex:
axios({
method: "get",
url: path,
params: params,
paramsSerializer: params => transformRequestOptions(params)
})
...
/**
* detect IE
* returns version of IE or false, if browser is not Internet Explorer
*/
function detectIE() {
const ua = window.navigator.userAgent
// Test values; Uncomment to check result …
// IE 10
// ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';
// IE 11
// ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';
// Edge 12 (Spartan)
// ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';
// Edge 13
// ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';
const msie = ua.indexOf('MSIE ')
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10)
}
const trident = ua.indexOf('Trident/')
if (trident > 0) {
// IE 11 => return version number
const rv = ua.indexOf('rv:')
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10)
}
const edge = ua.indexOf('Edge/')
if (edge > 0) {
// Edge (IE 12+) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10)
}
// other browser
return false
}
function gaussian(mean, stdev) {
var y2
var use_last = false
return function () {
var y1
if (use_last) {
y1 = y2
use_last = false
} else {
var x1, x2, w
do {
x1 = 2.0 * Math.random() - 1.0
x2 = 2.0 * Math.random() - 1.0
w = x1 * x1 + x2 * x2
} while (w >= 1.0)
w = Math.sqrt((-2.0 * Math.log(w)) / w)
y1 = x1 * w
y2 = x2 * w
use_last = true
}
var retval = mean + stdev * y1
if (retval > 0) return retval
return -retval
}
}
// make a standard gaussian variable
var standard = gaussian(10000, 15)
// make a bunch of standard variates
for (i = 0; i < 2000; i++) {
console.log(Math.floor(standard()))
}
var myArray = [
{ id: 1, name: 'Foo Bar', email: '[email protected]' },
{ id: 2, name: 'Bar Foo', email: '[email protected]' },
{ id: 3, name: 'Joe Ocean', email: '[email protected]' },
{ id: 3, name: 'Jenny Block', email: '[email protected]' },
]
function checkDuplicatePropertyValueInObject(propertyName, inputArray) {
var seenDuplicate = false,
testObject = {}
inputArray.map(function (item) {
var itemPropertyName = item[propertyName]
if (itemPropertyName in testObject) {
testObject[itemPropertyName].duplicate = true
item.duplicate = true
seenDuplicate = true
} else {
testObject[itemPropertyName] = item
delete item.duplicate
}
})
return seenDuplicate
}
console.log(
'Duplicate IDs: ' + checkDuplicatePropertyValueInObject('id', myArray)
)
console.log(
'Duplicate names: ' + checkDuplicatePropertyValueInObject('name', myArray)
)
console.log(
'Duplicate emails: ' + checkDuplicatePropertyValueInObject('email', myArray)
)
const copyrightCSS =
'font-weight: bold; font-size: 50px;color: red; text-shadow: 3px 3px 0 rgb(217,31,38) , 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(245,221,8) , 12px 12px 0 rgb(5,148,68) , 15px 15px 0 rgb(2,135,206) , 18px 18px 0 rgb(4,77,145) , 21px 21px 0 rgb(42,21,113)'
const warningTitleCSS =
'color:red; font-size:60px; font-weight: bold; -webkit-text-stroke: 1px black;'
const warningDescCSS = 'font-size: 18px;'
console.log('%c QCTECH ', copyrightCSS)
console.log('%cStop!', warningTitleCSS)
console.log(
'%cThis is a browser feature intended for developers. If someone told you to copy and paste something here to enable a website feature or "hack" someone\'s account, it is a scam and will give them access to your fundSystem account.',
warningDescCSS
)
console.log(
'%cSee http://www.iqichengtech.com for more information.',
warningDescCSS
)
;('b' + 'a' + +'a' + 'a').toLowerCase()
Array.from({ length: 12 }, (x, index) =>
new Date(0, index + 1, 0).toLocaleDateString('cn', { month: 'long' })
)
other code
Array.from({ length: 3 }, (_, i) => `day-${i}`)
Array.from({ length: 12 }, (x, index) => {
return index < 9 ? '0' + (index + 1) : index + 1 + ''
})
// Generate Array
;[...Array(N).keys()].map((i) => i + 1) // [1,2,3,...1000]
Array(N)
.fill()
.map((_, i) => i + 1)
Array.from(Array(N), (_, i) => i + 1)
Array.from({ length: N }, (_, i) => i + 1)
//
;[...Array(N).keys()].map(f)
Array(45)
.fill(0)
.map((e, i) => i + 1) // [1,...,45]
Array.from({ length: 5 }, (v, k) => k + 1) // [1,2,3,4,5]
in
element
tab panel,Ctrl+F
, then input.//*[@id='id']
, ex:.//*[@id='ax-8']
or inConsole
panel:
ex: in Ctrl+F
:
.//*[@id='ax-8']
.//img
- type in XPATH like
$x(".//*[@id='id']")
- type in CSS selectors like
$$('#id')
var C, I, A
C = I = A = 0 // Get it?
for (; I < 4; I++) {
for (; A < 101; A++) {
C++ // Get it???
}
A = 0
}
console.log(C) // output: 404
arr = [...Array[10]]
arr = [...Array(10).keys()]
arr = [...Array(10).fill(true)]
arr = [...Array(10)].map(Math.random)
arr.sort(() => 0.5 - Math.random())
const arr = [(x) => x * 1, (x) => x * 2, (x) => x * 3, (x) => x * 4]
arr.reduce((agg, el) => agg + el(agg), 1) // 120
// when you don't want to name the first parameter
arr.map((_iDontNeedThis, index) => index)
arr.map((...[, index]) => index)
// code
'' || 'foo' // => "foo"
undefined || 32 // => 32
var a = 0
a || 32 // => 32
expr && doSomething()
// Instead of
if (expr) {
doSomething()
}
function doSomething() {
return {
foo: 'bar',
}
}
var expr = true
var res = expr && doSomething()
res && console.log(res) // => { foo: "bar" }
// get First, Last element of Array
function getFirstLast(array) {
const { 0: first, length: len, [len - 1]: last } = array
return { first, last }
}
getFirstLast('apple') // => { first: "a", last: "e" }
getFirstLast(['foo', 'bar', 'baz', 'quux']) // => {first: "foo", last: "quux"}
// get a random item from an array
const items = [12, 548, 'a', 2, 5478, 'foo', 8852, , 'Doe', 2145, 119]
const randomItem = items[Math.floor(Math.random() * items.length)]
console.log(randomItem)
// Get a random number in a specific range
const x = Math.floor(Math.random() * (max - min + 1)) + min
// Generate an array of numbers with numbers from 0 to max
let numbersArray = []
let max = 100
for (var i = 1; numbersArray.push(i++) < max; ); // numbers = [1,2,3 ... 100]
// Generate a random set of alphanumeric characters
function generateRandomAlphaNum(len) {
let rdmString = ''
for (
;
rdmString.length < len;
rdmString += Math.random().toString(36).substr(2)
);
return rdmString.substr(0, len)
}
// Shuffle an array of numbers
var numbers = [5, 458, 120, -215, 228, 400, 122205, -85411]
numbers = numbers.sort(function () {
return Math.random() - 0.5
})
// `Comma Operator`
let a = 0
let b = (a++, 99)
console.log(a) // a will be equal to 1
console.log(b) // b will be equal to 99
// Array to Object method
const a = 'Wes Bos,ScottTolinski'.split('.')
a.map((x) => x.split(' '))
Object.fromEntries($_) // $_ is the last thing returned from dev tools.
const names = new Map()
names.set('wes', 'cool')
names.set('scott', 'neat')
Object.fromEntries(names)
// From anything to a number
var foo = '42'
var myNumber = +foo // shortcut for Number(foo)
// → 42
// Tip: you can convert it directly into a negative number
var negativeFoo = -foo // or -Number(foo)
// → -42
// From object to array
// Tip: `arguments` is an object and in general you want to use it as array
var args = { 0: 'foo', 1: 'bar', length: 2 }
Array.prototype.slice.call(args)
// → [ 'foo', 'bar' ]
// Anything to boolean
/// Non non p is a boolean p
var t = 1
var f = 0
!!t
// → true
!!f
// → false
/// And non-p is a boolean non-p
!t
// → false
!f
// → true
// Anything to string
var foo = 42
'' + foo // shortcut for String(foo)
// → "42"
foo = { hello: 'world' }
JSON.stringify(foo)
// → '{ "hello":"world" }'
JSON.stringify(foo, null, 4) // beautify the things
// →
// '{
// "hello": "world"
// }'
// Note you cannot JSON.stringify `circular structures`
JSON.stringify(window)
// ⚠ TypeError: JSON.stringify cannot serialize cyclic structures.
Airbnb JavaScript Style Guide
Airbnb
Google JavaScript Style Guide
Google JavaScript guide
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
clearTimeout(timeout)
// do something with response data
}
}
let timeout = setTimeout(function () {
xhr.abort() // call error callback
}, 60 * 1000 /* timeout after a minute */)
xhr.open('GET', url, true)
xhr.send()
WebSocket
timeout
let timerID = 0
function keepAlive() {
let timeout = 15000
if (webSocket.readyState == webSocket.OPEN) {
webSocket.send('')
}
timerId = setTimeout(keepAlive, timeout)
}
function cancelKeepAlive() {
if (timerId) {
cancelTimeout(timerId)
}
}
The
keepAlive()
function should be added at the end of theonOpen()
method of the webSocket connection and thecancelKeepAlive()
at the end of theonClose()
method.
let data = [20, 9320, 9010, 9340, 12900, 13300, 13200]
let arrayAverage = (arr) => arr.reduce((sum, x) => x + sum, 0) / arr.length
let averageArr = arrayAverage(data)
let differences = data.map((x) => x - averageArr).map((x) => x * x)
let averageDifference = arrayAverage(differences)
let standardDeviation = Math.sqrt(averageDifference)
console.log(standardDeviation) // output
// knockoutjs 方便调试
<!-- ko text: ko.toJSON($data) --><!-- /ko -->
<span data-bind="text: ko.toJSON($data)"></span>
<!-- ko foreach: selectedValue -->
<div>
<span data-bind="text: $data"></span>
</div>
<!-- /ko -->
const cars = [
{ name: 'Honda', miles: 1232 },
{ name: 'Ford', miles: 1233 },
{ name: 'Mercury', miles: 785 },
{ name: 'Highlander', miles: 11567 },
{ name: 'Expedition', miles: 214 },
{ name: 'Hatchback', miles: 2211 },
]
const carNames = Array.from(cars, ({ name }) => name)
console.log(carNames)
merge methods
const mergeA = (target, source) => Object.assign({}, target, source)
const mergeB = (target, source) => ({ ...target, ...source })
no repeats.
const values = [1, 1, 1, 2, 2, 3, 2]
/**
* Filters out values that repeat
* @param {object} value Value of the element in an Array
* @param {number} index Location of the element in the Array
* @param {Array} array Array being filtered
*/
const noRepeats = (value, index, array) => {
const isStart = index === 0
if (isStart || value !== array[index - 1]) {
return true
}
return false
}
values.filter(noRepeats) // [ 1, 2, 3, 2 ]
// Some questions to ask the user
const questions = [
{ title: 'What is your name?' },
{ title: 'What is your age?', cancel: true },
{ title: 'What is your dogs name?' },
]
// asyncMap util function
async function asyncMap(array, callback) {
const results = []
for (const item of array) {
// this await pauses the async function / for of loop
results.push(await callback(item))
}
return results
}
async function go() {
// the ask function pops up a modal dialog, so we can't just promise.all() and pop up three dialogs
const answers = await asyncMap(questions, ask)
console.log(answers)
}
go()
const relative = new Intl.RelativeTimeFormat('en', {
style: 'long',
numeric: 'auto',
})
relative.format(3, 'day')
relative.format(7, 'day')
relative.format(1, 'day')
relative.format(-2, 'day')
relative.format(100, 'year')
relative.format(-1, 'year')
relative.format(0, 'year')
relative.format(-20, 'second')
relative.format(10, 'second')
// make a function to handle that error
function handleError(fn) {
return function (...params) {
return fn(...params).catch(function (err) {
// do something with the error!
console.log(`Oops`, err)
})
}
}
// this is a big array of 76 items. I need to split into groups of 10
const hugeArray = Array.from({ length: 76 }, (_, i) => i)
function chunkify(array, chunkSize = 10) {
// make a new array
const chunks = Array.from(
// give it however many slots are needed - in out case 8
// 1-7 with 10 items, and 8th slot will have 6
{ length: Math.ceil(array.length / chunkSize) },
// this is map function that will fill up out slots
(_, i) => {
// make a slice of 100 items
const start = chunkSize * i
// slice our the piece of the array we need
return array.slice(start, start + chunkSize)
}
)
return chunks
}
console.log(chunkify(hugeArray))
/*
0: (10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1: (10) [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2: (10) [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
3: (10) [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
4: (10) [40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
5: (10) [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
6: (10) [60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
7: (6) [70, 71, 72, 73, 74, 75]
*/
// Or
function chunkArray(array, size) {
let result = []
for (let i = 0; i < array.length; i += size) {
let chunk = array.slice(i, i + size)
result.push(chunk)
}
return result
}
const faces = ['😀', '🤯', '🤡', '🤑', '🤩', '🐶', '😼', '😺']
function attachBody(face, body) {
return `
${face}
${body.repeat(3)}
${Array(3).fill(body).join(' ')}
👇 ${body.repeat(2)} 👇
${Array(2).fill(body).join(' ')}
${Array(2).fill(body).join(' ')}
🦶 🦶
`
}
faces.map((face) => attachBody(face, '🍟')).forEach((body) => console.log(body))
const array = ['need', '', 'to', null, 'clean', 0, false, 'up']
const clean = array.filter(Boolean)
console.log(clean)
async function asyncFunction() {
const promises = [
fetch('file1.json'),
fetch('file2.json'),
fetch('file3.json'),
fetch('file4.json'),
]
// Normal iterator
for (const item of promises) {
console.log(item)
}
// async iterator
for await (const item of promises) {
console.log(item)
}
}
class Cat {
constructor(name) {
this.name = name
}
speak() {
console.log(`${this.name} says MEOW`)
}
}
const cat = new Cat('Mojo')
cat.speak()
better
const createCat = (name) => ({ name })
const speak = ({ name }) => {
console.log(`${name} says MEOW`)
}
const cat = createCat('Mojo')
speak(cat)
const createCat = (name) => {
const speak = () => {
console.log(`${name} says MEOW`)
}
return {
name,
speak,
}
}
Promise.resolve({ some: 'data' })
.finally(() => { console.log('WHALE HELLO THERE 🧶') })
.then(data => ({ ...data, anAdditional: 'key' }))
.finally(() => { console.log('GOAT HELLO THERE 🎄') })
.then(data => { ...data, yetAnthor: 'thing added' })
.finally(() => { console.log('SHEEP HELLO THERE 🎭') })
.then(data => { console.log('Final result:', data) })
const functor = (value) => ({
value,
map: (func) => functor(func(value)),
inspect: () => `functor(${JSON.stringfy(value)})`,
})
const double = (number) => number * 2
functor(100).map(double).map(double).map(double)
other code
const cats = [
{ name: 'Mojo', months: 120 },
{ name: 'Sachi', months: 112 },
{ name: 'Kitty', months: 3 },
]
const isKitten = ({ months }) => months <= 6
const not = (func) => (arg) => !func(arg)
const isNotKitten = not(isKitten)
const kittens = cats.filter(isKitten)
const adultCats = cats.filter(isNotKitten)
for (
let i = (console.log('setting i to 0'), 0);
console.log(`i is ${i}`) || i < 5;
console.log(`${i} => ${++i}`)
);
102 Cool Table webdatarocks
function getUserIP(onNewIP) {
// onNewIp - your listener function for new IPs
//compatibility for firefox and chrome
var myPeerConnection =
window.RTCPeerConnection ||
window.mozRTCPeerConnection ||
window.webkitRTCPeerConnection
var pc = new myPeerConnection({
iceServers: [],
}),
noop = function () {},
localIPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key
function iterateIP(ip) {
if (!localIPs[ip]) onNewIP(ip)
localIPs[ip] = true
}
onNewIP
//create a bogus data channel
pc.createDataChannel('')
// create offer and set local description
pc.createOffer()
.then(function (sdp) {
sdp.sdp.split('\n').forEach(function (line) {
if (line.indexOf('candidate') < 0) return
line.match(ipRegex).forEach(iterateIP)
})
pc.setLocalDescription(sdp, noop, noop)
})
.catch(function (reason) {
// An error occurred, so handle the failure to connect
})
//listen for candidate events
pc.onicecandidate = function (ice) {
if (
!ice ||
!ice.candidate ||
!ice.candidate.candidate ||
!ice.candidate.candidate.match(ipRegex)
)
return
ice.candidate.candidate.match(ipRegex).forEach(iterateIP)
}
}
getUserIP(console.log)
window.RTCPeerConnection =
window.RTCPeerConnection ||
window.mozRTCPeerConnection ||
window.webkitRTCPeerConnection //compatibility for Firefox and chrome
var pc = new RTCPeerConnection({ iceServers: [] }),
noop = function () {}
pc.createDataChannel('') //create a bogus data channel
pc.createOffer(pc.setLocalDescription.bind(pc), noop) // create offer and set local description
pc.onicecandidate = function (ice) {
if (ice && ice.candidate && ice.candidate.candidate) {
var myIP =
/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(
ice.candidate.candidate
)[1]
console.log('my IP: ', myIP)
pc.onicecandidate = noop
}
}
104 文本过多,横向滚动显示codepen
其他好的滚动资源
105 Homebrew 配置USTC
源
Homebrew Bottles
: Homebrew 预编译二进制软件包
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.bash_profile
source ~/.bash_profile
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles' >> ~/.zshrc
source ~/.zshrc
homebrew core
: 使用 USTC 源
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
重置为官方地址
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://github.com/Homebrew/homebrew-core
homebrew cask
: 提供 macOS 应用和大型二进制文件
cd "$(brew --repo)"/Library/Taps/homebrew/homebrew-cask
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-cask.git
重置为官方地址:
cd "$(brew --repo)"/Library/Taps/homebrew/homebrew-cask
git remote set-url origin https://github.com/Homebrew/homebrew-cask
Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15)
const toKeyValue = ([key, value]) => ({ key, value })
const toIterable = (object) => ({
...object,
[Symbol.iterator]: function () {
const entries = Object.entries(this)
let current = 0
const next = () =>
current < entries.length
? { done: false, value: toKeyValue(entries[current++]) }
: { done: true }
return { next }
},
})
const object = { a: 1, b: 2, c: 3 }
const iterable = toIterable(object)
const entries = [...iterable]
for (let i of iterable) {
console.log(i)
}
.scroller {
width: 300px;
height: 100px;
overflow-y: scroll;
scrollbar-color: rebeccapurple green;
scrollbar-width: thin;
}
109 Values contained in a closure will be "private" to the environment outside of the closure;Funfctions inc
and dec
have exclusive access to state
;state
is protected from outside changes
function createCounter(start = 0) {
let state = start
const inc = () => ++state
const dec = () => --state
return { inc, dec }
}
// Ex
const { inc, dec } = createCounter()
inc() //? 1
inc() //? 2
inc() //? 3
dec() //? 2
dec() //? 1
const pipe =
(...funcs) =>
(v) => {
funcs.reduce((res, func) => {
return func(res)
}, v)
}
const minusFive = (v) => v - 5
const addFour = (v) => v + 4
const multiplyByTen = (v) => v * 10
pipe(minusFive, addFour, multiplyByTen, Math.abs, console.log)(0) // 10
using
&
with1
function isEven(num) {
if (num & 1) {
return false
} else {
return true
}
}
or using
recursive
function
function isEven(num) {
if (num < 0 || num === 1) return false
if (num == 0) return true
return isEven(num - 2)
}
const slice = Array.prototype.slice
function memoize(fn) {
const cache = {}
return (...args) => {
const params = slice.call(args)
console.log(params)
if (cache[params]) {
console.log('cached')
return cache[params]
} else {
let result = fn(...args)
cache[params] = result
console.log(`not cached`)
return result
}
}
}
const makeFullName = (fName, lName) => `${fName} ${lName}`
const reduceAdd = (numbers, startingValue = 0) =>
numbers.reduce((total, cur) => total + cur, startingValue)
const memoizedMakeFullName = memoize(makeFullName)
const memoizedReduceAdd = memoize(reduceAdd)
memoizedMakeFullName('Marko', 'Polo')
memoizedMakeFullName('Marko', 'Polo')
memoizedReduceAdd([1, 2, 3, 4, 5], 5)
memoizedReduceAdd([1, 2, 3, 4, 5], 5)
<!-- 方法1 -->
<pre>{{data}}<pre>
<!-- 方法2 -->
<span style="white-space: pre;">{{data}}</span>
in
dist
folder, touchWEB-INF/web.xml
file, add following content to web.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" metadata-complete="true">
<display-name>saasweb</display-name>
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
</web-app>
var first = [1, 2, 3]
var second = [1, 2, 3]
var third = [3, 2, 1]
var fourth = [1, 3]
var fifth = [0, 1, 2, 3, 4]
console.log(compareArrays(first, second))
console.log(compareArrays(first, third))
console.log(compareArrays(first, fourth))
console.log(compareArrays(first, fifth))
function compareArrays(first, second) {
//write type error
return (
first.every((e) => second.includes(e)) &&
second.every((e) => first.includes(e))
)
}
const user = {
id: 100,
name: 'test',
password: 'password',
}
const removeProperty =
(prop) =>
({ [prop]: _, ...rest }) =>
rest
const removePassword = removeProperty('password')
removePassword(user)
117. ag-grid older version document18.1.0
string.split('')
;[...string]
Array.from(string)
Object.assign([], string)
const number = (2020202 / 10) | 0
121. Generate Random whole numbers Stackoverflow
function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// If all redicate function returen true for all elements, return true
const all = (arr, fn = Boolean) => arr.every(fn)
all([4, 2, 3], (x) => x > 1) // true
all([1, 2, 3]) // true
// check all elements in an array are equal.
const allEqual = (arr) => arr.every((val) => val === arr[0])
allEqual([1, 2, 3, 4, 5, 6]) // false
allEqual([1, 1, 1]) // true
// return the average of numbers
const average = (...nums) =>
nums.reduce((acc, val) => acc + val, 0) / nums.length
average(...[1, 2, 3]) // 2
average(1, 2, 3) // 2
// return the length of a string in bytes
const byteSize = (str) => new Blob([str]).size
byteSize('😀') // 4
byteSize('Hello World') // 11
// remove falsy values from an array
const compact = (arr) => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]) // [ 1, 2, 3, 'a', 's', 34 ]
// gets the day of the year from a Date object
const dayOfYear = (date) =>
Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24)
dayOfYear(new Date()) // 98
// converts an angle from degrees to radians.
const degreesToRads = (deg) => (deg * Math.PI) / 180.0
degreesToRads(90.0) // ~1.5708
// returns the difference between two arrays.
const difference = (a, b) => {
const s = new Set(b)
return a.filter((x) => !s.has(x))
}
difference([1, 2, 3], [1, 2, 4]) // [3]
// returns the distance between two points.
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0)
distance(1, 1, 2, 3) // 2.23606797749979
// returns a new array with n elements removed from the left.
const drop = (arr, n = 1) => arr.slice(n)
drop([1, 2, 3]) // [2,3]
drop([1, 2, 3], 2) // [3]
drop([1, 2, 3], 42) // []
// returns every nth element in an array.
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1)
everyNth([1, 2, 3, 4, 5, 6], 2) // [ 2, 4, 6 ]
// calculates the factorial of a number.
const factorial = (n) =>
n < 0
? (() => {
throw new TypeError('Negative numbers are not allowed!')
})()
: n <= 1
? 1
: n * factorial(n - 1)
factorial(6) // 720
[optional]:在评论前面加上一个[optional]标记,表示这个代码行的问题可改可不改 [question]:在评论前面加上一个[question]标记,表示对这个代码行不理解,有问题需要问,被审查者需要针对问题进行回复澄清 类似这样的分级可以帮助被审查者直观了解 Review 结果,提高 Review 效率
const validateUrl = (url) => {
try {
new URL(url)
return true
} catch {
return false
}
}
console.log(validateUrl('aaa'))
console.log(validateUrl('http://aaa.com'))
parseInt(
11101000,
2
)(
// 232
232
).toString(2) // "11101000"
can't write
1.toString()
// should
;(1).toString()
;(1).toString()(1).toString()
;(1.0).toString()
127. Compare nonintegers, take an upper bound. Such an upper bound is called a machine epsilon
. The standard epsilon value for double precision is 2^-53
let EPSILON = Math.pow(2, -53)
function epsEqu(x, y) {
return Math.abs(x - y) < EPSILON
}
// usage
0.1 + 0.2 === 0.3 // false
epsEqu(0.1 + 0.2, 0.3) // true
The result of the remainder operator always has the sign of the first operand (for modulo, it is the sign of the second operand):
;-5 % 2 // -1
//That means that the following function does not work:
// Wrong!
function isOdd(n) {
return n % 2 === 1
}
console.log(isOdd(-5)) // false
console.log(isOdd(-4)) // false
// The correct version is:
function isOdd(n) {
return Math.abs(n % 2) === 1
}
console.log(isOdd(-5)) // true
console.log(isOdd(-4)) // false
proto is pronounced “dunder proto,” an abbreviation of “double underscore proto.” That pronunciation has been borrowed from the Python programming lan‐ guage (as suggested by Ned Batchelder in 2006). Special variables with double un‐ derscores are quite frequent in Python.
console.log(JSON.stringify(data, null, 4));
console.log(JSON.stringify({a: 0, b: ['\n']}, null, '|--'));
console.log(JSON.stringify(function() {})); // undefined
console.log(JSON.stringify({ foo: function() {} })); // '{}'
console.log(JSON.stringify([ function () {} ])); // '[null]'
// The toJSON() Method
console.log(JSON.stringify({ toJSON: function () { return 'Cool' } })); // '"Cool"'
// Dates already have a toJSON method that produces an ISO 8601 date string
console.log(JSON.stringify(new Date('2011-07-29'))); // '"2011-07-28T22:00:00.000Z"'
// built-in toJSON() methods
let obj={
toJSON: function (key) {
// Use JSON.stringify for nicer-looking output
console.log(JSON.stringify(key));
return 0;
}
};
JSON.stringify({ foo: obj, bar: [ obj ]})
// "foo"
// "0"
// '{"foo":0,"bar":[0]}'
//• Boolean.prototype.toJSON()
//• Number.prototype.toJSON()
//• String.prototype.toJSON()
//• Date.prototype.toJSON()
// JSON.parse(text, reviver?)
function dateReviver(key, value) {
if (typeof value === 'string') {
let x = Date.parse(value);
if (!isNaN(x)) { // valid date string?
return new Date(x);
}
}
return value;
}
let str = '{ "name": "John", "birth": "2011-07-28T22:00:00.000Z" }';
console.log(JSON.parse(str, dateReviver));
// { name: 'John', birth: Thu, 28 Jul 2011 22:00:00 GMT }
const context = new AudioContext()
const oscillator = context.createOscillator()
oscillator.frequency.value = 448
oscillator.connect(context.destination)
oscillator.start()
oscillator.stop()
/**
* 包含浏览器检测的contains()方法
*
* compareDocumentPosition() 确定2个节点间关系,返回表示该关系的位掩码(bitmask)
* 1 无关
* 2 居前
* 4 居后
* 8 包含
* 16 被包含
*/
function contains(refNode, otherNode) {
if (
typeof refNode.contains == 'function' &&
(!client.engine.webkit || client.engine.webkit >= 522)
) {
return refNode.contains(otherNode)
} else if (typeof refNode.compareDocumentPosition == 'function') {
return !!(refNode.compareDocumentPosition(otherNode) & 16)
} else {
let node = otherNode.parentNode
do {
if (node === refNode) {
return true
} else {
node = node.parentNode
}
} while (node !== null)
return false
}
}
let allList = []
const filterBy = {
trhFrom: '123',
modelId: 'CRH380D',
date: '2021-04-26',
}
let filterByList = allList.filter((o) => {
return Object.keys(filterBy).every((k) => {
if (filterBy[k]) {
return filterBy[k].includes(o[k])
}
return true
})
})
console.log(filterByList)
const MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24
function dayDifference(date1, date2) {
const timeDiff = Math.abs(date2.getTime() - date1.getTime())
const diffDays = Math.ceil(timeDiff / MILLISECONDS_PER_DAY)
return diffDays
}
let date1 = new Date() //May 28 2019
let date2 = new Date()
date2.setDate(22)
dayDifference(date, date1) // 7
135. display: inline-block
或 overflow: hidden
引起的元素高度莫名增大
-
引起原因:与
inline-block
的元素的 baseline 定义与实现有关,参考w3c 关于元素 baseline 的说明 -
解决方法:加
vertial-align:top
或别的值, 参考stackoverflow 解决方法
目的:不想升级一个npm
包,但是想用它的一些新功能,可以在一个项目中安装不同版本的npm
包,以react
为例。
准备:node
及npm
版本要求
NPM version: 6.9.0 or above 发布说明
Node version: 10.16.0 or above 发布说明
安装:使用 package aliases 命令实现
npm i <package_name_alias>@npm:<package_name>
例如:安装最新版本的react
,别名为react-latest
# 安装
npm i react-latest@npm:react
// 项目中引用
import React from 'react-latest'
# 安装一个确定版本的包
npm i react-latest@npm:[email protected]
对应的package.json
文件为
{
"name": "project-name",
"version": "1.0.0",
"dependencies": {
"react": "15.5.0",
"react-latest": "npm:react@^16.8.0"
}
}
const isRequired = () => {
throw Error('Argument is missing')
}
const setUsername = (username = isRequired()) => {
// Do something with `username`
// If `username` is not provided,
// these lines of code will never be reached.
}
data:text/html,<canvas id="v"
><script>
;(d = document),
(P = 'onpointer'),
(c = v.getContext('2d')),
(v.width = innerWidth),
(v.height = innerHeight),
(f = 0),
(d[P + 'down'] = (e) => {
f = e.pointerId + 1
e.preventDefault()
c.beginPath()
c.moveTo(e.x, e.y)
})
;(d[P + 'move'] = (e) => {
f == e.pointerId + 1 && c.lineTo(e.x, e.y)
c.stroke()
}),
(c.lineWidth = 3),
(d[P + 'up'] = (_) => (f = 0))
</script></canvas
>
function findMinMax(arr) {
let min = arr[0].y,
max = arr[0].y
for (let i = 1, len = arr.length; i < len; i++) {
let v = arr[i].y
min = v < min ? v : min
max = v > max ? v : max
}
return [min, max]
}
let data = [
'CRH390BL-2011',
'CRH390BL-1011',
'CRH380BL-3019',
'CRH390BL-2001',
'CRH380BL-5019',
'CRH380BL-5060',
'CRH390BL-5051',
'CRH2A-2011',
'CRH2B-2221',
'CRH3A-4011',
]
let op = (arr) =>
arr.sort(
new Intl.Collator('en', {
numeric: true,
sensitivity: 'accent',
}).compare
)
console.log(op(data))
wmic bios get serialnumber
const fail = (message) => {
throw Error(message)
}
const given = (f) => f()
const destructure =
(strings, ...variables) =>
(target) =>
['', ...variables].reduce(
(accum, name, index) =>
given(
(
needle = strings[index],
found = index === variables.length
? target.length
: target.indexOf(needle, accum.index)
) =>
found === -1
? fail(`Target string did not match template.`)
: (index !== 0 &&
(accum.results[name] = target.slice(accum.index, found)),
(accum.index = found + needle.length),
accum)
),
{ index: 0, results: {} }
).results
const testURL = 'https://google.com/pizza/pie'
const { host, path } = destructure`https://${'host'}/${'path'}`(testURL)
function toUnicode(str) {
return str
.split('')
.map(function (value, index, array) {
var temp = value.charCodeAt(0).toString(16).toUpperCase()
if (temp.length > 2) {
return '\\u' + temp
}
return value
})
.join('')
}
toUnicode('替代描述') // "\u66FF\u4EE3\u63CF\u8FF0"
function censor(censor) {
var i = 0
return function (key, value) {
if (
i !== 0 &&
typeof censor === 'object' &&
typeof value == 'object' &&
censor == value
)
return '[Circular]'
if (i >= 29) return '[Unknown]'
++i
return value
}
}
const a = {}
a.b = 1
a.c = 2
a.d = a
JSON.stringify(a, censor(a))
const getNode = (el) => {
const treeWalker = document.createTreeWalker(
el || document.body,
NodeFilter.SHOW_ELEMENT,
{
acceptNode: function (node) {
return NodeFilter.FILTER_ACCEPT
},
},
false
)
let nodeList = []
let currentNode = treeWalker.currentNode
while (currentNode) {
nodeList.push(currentNode)
currentNode = treeWalker.nextNode()
}
return nodeList
}
const nodeNameList = (nodeList) => {
return [...nodeList].map((o) => o.nodeName)
}
const count = (arr) => {
return arr.reduce(
(prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev),
{}
)
}
console.log(count(nodeNameList(getNode($0)))) // output: {P: 1, CODE: 8, EM: 2}
const extractDate = (rawStr) => {
const str = 'Y' + rawStr
const arr = str?.match(/[YQMW][0-9]{1,4}/g)
return arr?.reduce((acc, cur) => {
return {
...acc,
[cur[0]]: cur.slice(1),
}
}, {})
}
extractDate('2021Q3M9W1') // { Y: '2021', Q: '3', M: '9', W: '1' }
- npm ---------- https://registry.npmjs.org/
- yarn --------- https://registry.yarnpkg.com/
- tencent ------ https://mirrors.cloud.tencent.com/npm/
- cnpm --------- https://r.cnpmjs.org/
- taobao ------- https://registry.npmmirror.com/
- npmMirror ---- https://skimdb.npmjs.com/registry/
export function getUid() {
return getUid._uid++
}
getUid._uid = 0
getUid() // 0
getUid() // 1
getUid() // 2
export function humanReadableFileSize(
bytes: number,
base: 1000 | 1024 = 1000
): string {
if (bytes < base) {
return `${bytes} B`
}
const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G']
let unit = -1
while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
bytes /= base
++unit
}
return `${bytes.toFixed(1)} ${prefix[unit]}B`
}
alias wechat="nohup /Applications/WeChat.app/Contents/MacOS/WeChat > /dev/null 2>&1"
// input: 34567 step: 10000
// output: ['1-10000', '10001-20000', '20001-34567']
// @lusai solution
const num = 34567
const step = 10000
const arr = num.toString().split('').map(Number)
const targetArrayLength = arr[0] + 1
let flag = 0
let targetArray = []
for (let index = 0; index < targetArrayLength; index++) {
targetArray.push(
`${flag + 1}-${step * (index + 1) > num ? num : step * (index + 1)}`
)
flag = step * index > num ? num : step * (index + 1)
}
console.table(targetArray)
// ===
// @majinping solution
const imageNum = 34567
const step = 10000
const arrLength = Math.ceil(imageNum / step)
const result = Array.from({ length: arrLength }).map((_, index) => {
let endNum = (index + 1) * step
if (index === arrLength - 1) {
endNum = imageNum
}
return [index * step + 1, endNum]
})
console.log(
'image number: ',
imageNum,
'\noptions: ',
result.map((item) => item.join('-')).join(','),
'\noptionsArr: ',
result
)
console.table($$('*[id]'), ['tagName', 'id'])
Vue.prototype.$confirmWithoutEnter = (message, title, options) =>
MessageBox.confirm(message, title, {
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
instance.$refs['confirm'].$el.onclick = (function (e) {
e = e || window.event
if (e?.detail !== 0) {
done()
}
})()
} else {
done()
}
},
...(options || {}),
})
- 1 fetch index.html as text, add
timestamp
avoiding cache. - 2 calc hash, using
SHA256
etc. - 3 compare old hash and latest file hash polling.
- 4 notify user refresh page.
Ex: Vuejs compositionAPI
import { ref } from '@vue/composition-api'
import { useIntervalFn } from '@vueuse/core'
import sha256 from 'crypto-js/sha256'
let hasNewVersion = ref(false)
const pageHashSymbol = 'page_hash'
const pollInterval = 5000 // 5 second
const getPage = async () => {
const response = await fetch(
`${
window.location.origin + process.env.VUE_APP_CI_PROJECT_NAME
}/index.html?s=${new Date().getTime()}`
).catch((err) => {
console.log(err)
})
if (response.status !== 200) {
hasNewVersion.value = false
throw new Error(`🥲 Error: `, err)
}
return await response.text()
}
const checkDiff = async () => {
const html = await getPage()
if (!html) return
if (!window.localStorage.getItem(pageHashSymbol)) {
window.localStorage.setItem(pageHashSymbol, sha256(html).toString())
hasNewVersion.value = false
} else {
hasNewVersion.value =
sha256(html).toString() !== window.localStorage.getItem(pageHashSymbol)
}
}
useIntervalFn(checkDiff, pollInterval)
const refreshPage = async () => {
const html = await getPage()
window.localStorage.setItem(pageHashSymbol, sha256(html).toString())
window.location.reload()
}
<template>
<div @click="refreshPage">
{{ hasNewVersion ? 'Has New Version, please refresh page' : null }}
</div>
</template>
use
defu
const { mergeDeepWith } = require("[email protected]")
const original = {
x: {
y: 123,
z: {
a: {
b: null
}
}
},
user: {
menu: {
codes: []
},
info: {
name: null,
age: null
}
}
}
const responseData = {
x: {
y: 123,
z: null
},
user: {
menu: null,
info: {
name: 'James',
age: 37,
},
},
}
const result = mergeDeepWith(
(oldVal, newVal) => {
if ([null, '', undefined].includes(newVal)) {
return oldVal
}
return newVal
},
original,
responseData
)
console.error(result)
/**
* x: {
y: 123,
z: {
a: {
b: null
}
}
},
user: {
menu: {
codes: []
},
info: {
name: ’James‘,
age: 37
}
}
*/
—
const abortController = new AbortController();
const signal = abortController.signal;
const fetch1 = fetch('https://api.example.com/data-1', { signal });
const fetch2 = fetch('https://api.example.com/data-2', { signal });
const timeout = new Promise((_, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error('Request timeout'));
abortController.abort(); // Abort the fetch request
clearTimeout(timeoutId); // clear the timeout
}, 5000);
});
Promise.race([fetch1, fetch2, timeout])
.then((response) => console.log(response))
.catch((error) => console.error(error));
——
const request = (url, options = {}, maxRetry = 5) => {
return fetch(url, ...options).catch((error) => {
maxRetry <= 0 ? Promise.reject(error) : request(url, {}, maxRetry - 1)
})
}
const createCopyTextContent = () => {
if (navigator.clipboard) {
return (text) => {
navigator.clipboard.writeText(text)
}
} else {
return (text) => {
const inputEl = document.createElement('input')
inputEl.setAttribute('value', text)
document.body.appendChild(inputEl)
inputEl.select()
document.execCommand('copy')
document.body.removeChild(inputEl)
}
}
}
const copyTextContent = createCopyTextContent()
const generateOTP = () => {
const digits = '0123456789'
let otp = ''
for (let i = 0; i < 6; i++) {
otp += digits[Math.floor(Math.random() * 10)]
}
return otp
}
generateOTP()
const emojis = [`🔥`, `🤼♂️`, '👨👩👦👦']
emojis.forEach((s) => {
console.log(`${s} `, s.length) // 2 5 11
})
const stringLength = (str) => {
return Array.from(new Intl.Segmenter().segment(str)).length
}
emojis.forEach((s) => {
console.log(`${s} `, stringLength(s)) // 1 1 1
})
function logPropertyUpdates(target) {
if (typeof target === 'object' && target !== null) {
return new Proxy(target, {
get(target, property, receiver) {
const value = Reflect.get(target, property, receiver)
return logPropertyUpdates(value)
},
set(target, property, value, receiver) {
console.log(`Property "${property}" changed to "${value}"`)
return Reflect.set(target, property, value, receiver)
},
})
}
return target
}
const user = logPropertyUpdates({
name: 'Lew',
details: {
age: 24,
country: 'USA',
},
})
user.name = 'Kareem'
user.details.age = 25
const clearAds = () => {
const divz = document.getElementsByTagName('DIVZ')
const ads = [...document.querySelectorAll('div')].filter(
(s) => s.id.includes('left') || s.id.includes('right')
)
const ad2 = document.getElementsByClassName('adpcc')
;[...divz, ...ad2, ...ads].forEach((el) => {
el?.remove()
})
}
setTimeout(() => {
clearAds()
}, 5000)
163. Watch slot content changes using MutationObserver API
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
const slotElement = ref(null)
const observer = ref(null)
const update = () => {
console.log('UPDATE')
}
onMounted(() => {
observer.value = new MutationObserver(update)
observer.value.observe(slotElement.value, { childList: true, subtree: true })
})
onBeforeUnmount(() => {
if (observer.value) {
observer.value.disconnect()
}
})
</script>
<template>
<div ref="slotElement">
<slot />
</div>
</template>
function timed(f) {
return function (...args) {
console.log(`Entering function ${f.name}`)
let startTime = Date.now()
try {
return f(...args)
} finally {
console.log(`Exiting ${f.name} after
${Date.now() - startTime}ms`)
}
}
}
function benchmark(n) {
let sum = 0
for (let i = 1; i <= n; i++) sum += i
return sum
}
timed(benchmark)(1000000)
window.location = `https://${0.1 + 0.2}.com`
class Bar {
constructor() {
this[Symbol.toPrimitive] = function (hint) {
switch (hint) {
case 'number':
return 3
case 'string':
return 'string bar'
case 'default':
default:
return 'default bar'
}
}
}
}
let bar = new Bar()
console.log(3 + bar) // "3default bar"
console.log(3 - bar) // 0
console.log(String(bar)) // "string bar"
other useful Symbol function,
toStringTag
,search
,replace
,toStringTag
let s = new Set()
console.log(s) // Set(0) {}
console.log(s.toString()) // [object set]
console.log(s[Symbol.toStringTag]) // Set
class Foo {}
let foo = new Foo()
console.log(foo) // Foo {}
console.log(foo.toString()) // [object Object]
console.log(foo[Symbol.toStringTag]) // undefined
class Bar {
constructor() {
this[Symbol.toStringTag] = 'Bar'
}
}
let bar = new Bar()
console.log(bar) // Bar {}
console.log(bar.toString()) // [object Bar]
console.log(bar[Symbol.toStringTag]) // Bar
167. Cross document messaging, sometimes abbreviated as XDM
, pass information between different execution contexts, such as web workers or pages from different origins. XDM could use postMessage
, MessageChannel
, BroadcastChannel
The definition of
postMessage
's first argument changed to allow any structured data; however, not all browsers have implemented this change. So, it's best to always pass a string
-
- Widget roles like button, checkbox
-
- Composite roles like separator , tab , or scrollbar combobox and listbox (these are for dropdown menus), radiogroup , or tree
-
- Document structure this includes directory
-
- Landmark banner article, presentation, figure, main, navigation, and feed, and region are roles in this category
-
- Live region alert, log, marquee, and status are roles that might update with real-time information
-
- Window alert dialog and dialog are the only two roles in this category
const formData = new FormData()
formData.append('a', 1)
formData.append('b', 2)
const v = Object.fromEntries(formData.entries())
console.log(v)