等价变换
把一个对象用数字代替,如ASCII码,再用一个物体的长度当做一,求出一点
do...while方法
do..while 保证第一个执行,用于对嵌套方法return的处理
let index = 0;
do{
let res = tasks[index++]()
}
while(res === undefined && index < tasks.length)
reduce()累加应用
reduce数组累加可以处理像then()类似的处理
let [first, ...others] = tasks
let res = first()
others.reduce((a,b)=>{b(a)},res)
重复执行指定次数
tasks.forEach(task=>{
let res
do{
res = task(...args)
}
while(res != undefined)
})
防止重复点击
防抖,2500内点击清除闭包的变量
$('textarea').on('keydown', debounce(ajaxAction, 2500));
function debounce(fn, delay){
var timer = null; // 声明计时器
return function() {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
闭包计算
{
let index = 0
let done = () => {
index++;
if(...)
}
this.tasks.forEach(task=>{
task(...args, done);
})
}
异步并行
callAsync(..args){
let finalCallback = args.pop()
let index = 0;
let next = () => {
if (this.tasks.length === index) return finalCallback()
let task = this.tasks[index++]
task(...args,next)
}
next()
}
向下迭代
callAsync(..args){
let finalCallback = args.pop()
let index = 0;
let next = () => {
let task = this.tasks[index];
// 做索引溢出处理
if (!task) return finalCallback();
// 传不同参数
if (index === 0){
task(...args, next);
} else {
task(data, next);
}
}
next()
}
hook.tapAsync('react', function (name, cb){
setTimeout(() => {
console.log('react', name)
cb(null, '结果') // 可以理解为next
}, 1000)
})
字符串拼接
使用exec()正则分割,使用arr.join(\r\n)
大数相加
// 转换成字符串进行操作
// https://blog.csdn.net/yulinjiayuan/article/details/98704883
function sub(a,b){
var res='', c=0;
a = a.split('');
b = b.split('');
while (a.length || b.length || c){
c += ~~a.pop() + ~~b.pop();
res = c % 10 + res;
c = c>9;
}
return res.replace(/^0+/,'');
}
// https://zhuanlan.zhihu.com/p/72179476
let a = "9007199254740991";
let b = "1234567899999999999";
function add(a ,b){
//取两个数字的最大长度
let maxLength = Math.max(a.length, b.length);
//用0去补齐长度
a = a.padStart(maxLength , 0);//"0009007199254740991"
b = b.padStart(maxLength , 0);//"1234567899999999999"
//定义加法过程中需要用到的变量
let t = 0;
let f = 0; //"进位"
let sum = "";
for(let i=maxLength-1 ; i>=0 ; i--){
t = parseInt(a[i]) + parseInt(b[i]) + f;
f = Math.floor(t/10);
sum = t%10 + sum;
}
if(f == 1){
sum = "1" + sum;
}
return sum;
}
发布订阅
- 发布订阅模式有中间代理
- 观察者模式
- 主体 存放观察者的数组,提供通知的方法
- 观察者 用来通知所以通知者状态更新
class Observer {
constructor(name, subject) {
this.name
this.subject
this.subject.attach(this)
}
update() {
}
}
// 主体
class Subject {
constructor() {
this.observers = []
state: ''
}
getState(){}
setState(){}
attach(observer){}// 系上
notifyAllObservers(){}// 通知
}
对象数组去重
- 新建变量
- 跟据特性
[{a: 1}, {a: 1}, {b: 2}], a
// 通过新建一个set对象存取唯一,再跟据key找arr中的值
// Array.from(new Set(arr.map(e => e[key]))) // [1, 2]
var clearDuplicate1 = (arr, key) => Array.from(new Set(arr.map(e => e[key]))).map(e => arr.find(x => x[key] == e));
// 跟进key过滤,再用findIndex找第一个元素的索引,再用index返回
var clearDuplicate2 = (arr, key) => Array.from(new Set(arr.map(e => e[key]))).map(e => arr.findIndex(x => x[key] == e)).map(e => arr[e])
// reduce,在迭代中找当前值,没有合并 ** 可以加上一个对象计算
var clearDuplicate3 = (arr, key) => arr.reduce((acc, current) => {
const x = acc.find(item => item[key] === current[key]);
if (!x) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
// set的has方法判断当前值存不存在
var clearDuplicate4 = (arr, key) => {
var set = new Set()
return arr.filter(e => {
var duplicate = set.has(e[key])
set.add(e[key])
return !duplicate
})
}
// 跟据索引
var clearDuplicate5 = (arr, key) => arr.filter((ele, index, a) => (a.map(e => e[key]).indexOf(ele[key])) ===index)
/* 普通数据去重 */
// 跟据对象去重
function unique(arr) {
var array = [],obj = {}
for (var i = 0; i < arr.length; i++) {
if (!obj[arr[i]]){
array.push(arr[i])
obj[arr[i]] = 1
}else{
obj[arr[i]]++
}
}
return array
}
// set去重
function unique (arr) {
return Array.from(new Set(arr))
}
[...new Set(arr)]
// sort()排序
arr = arr.sort()
var array = [arr[0]]
for (var i = 1; i<arr.length;i++){
if(arr[i] !== arr[i-1]) {
array.push(arr[i])
}
}
// array.prototype.includes() 是否包含一个指定的值,返回true,false
if (!array.includes(arr[i])){
array.push(arr[i])
}
// hasOwnProperty()
return arr.filter(item => {
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
数据校验
使用typeof
typeof null // "object" 可以将null认为是一个特殊的对象值,含义是“非对象。”
const obj = {
a: "object"
}
Boolean(obj && typeof obj === 'object')
使用async-validator // 对数据进行异步校验的库
循环访问
['name', 'age'].forEach(function(item) {
console.log(person[item]);
})
工厂模式
var createPerson = function(name, age) {
// 声明一个中间对象,该对象就是工厂模式的模子
var o = new Object();
// 依次添加我们需要的属性与方法
o.name = name;
o.age = age;
o.getName = function() {
return this.name;
}
return o;
}
// 创建两个实例js
var perTom = createPerson('TOM', 20);
var PerJake = createPerson('Jake', 22);
"1.工厂函数和构造函数不一样吗?"
> https://www.jb51.net/article/160770.htm
> https://wenwen.sogou.com/z/q742751999.htm
1. 工厂函数有返回值
2. 工厂函数时先生产一个对象,再返回该对象,所以原型链并不指向工厂函数而是object,构造函数指向该类
"2.v-model input val '' + '' ,r.repaymentAmount = checkInput(String(r.repaymentAmount))r undifined'时会输入不了为什么?"
> https://www.jianshu.com/p/6164d384dce5
双向绑定失效
input可以设置值,el-input => this.$nextTick()
"3.回显需要做多余的赋值操作,如何处理比较简单?"
// 先声明容器比如this.res
// 对象
["date","userID","username","avatar"].forEach((key)=>{
if(key in res){
this[key]=res[key]
}
})
// 数组
let [a,[b,[c,d]]] = [1,[2,[3,4]]];
// store //-第二种 /*- 第三种
export default {
mounted () {
this.$store.dispatch('getKindList')
// let { $store: { dispatch } } = this;dispatch('getKindList')
/*this.getKindList()*/
}
/* methods: {
...mapActions({
getKindList: 'getKindList'
})*/
},
computed: {
kindlist () {
return this.$store.state.kind.kindlist
}
// kindlist () {
// let { $store: { state: { kind: { kindlist } } } } = this
// return kindlist
/*...mapState({
kindlist: ({ kind: { kindlist } }) => kindlist
})*/
}
}
}
"4.Express 设置静态资源可跨域"
"5.如何置顶操作"
1.找到scroll所属的div
2.再设置$el.scrollTop = 10;
"6.如何避免在嵌套多层时使用多次display:flex"
Math.floor向下取整400.99999999
Math.floor(Math.random() * (maxHeight - minHeight + 1) + minHeight);