数字和字符串互换
parseInt() 解析一个字符串,并返回一个整数 ,默认基数为10,可以转换成其它不同的进制,当存在小数点时会只保留整数(可使用 parseFloat 转换成浮点数 ),在遇到不能解析的字符时就返回已经解析的整数部分,如果第一个字符就不能解析,就直接返回 NaN;Number() 把值转换为数字 ,如果值无法转换为数字(如字母,{},undefined),那么 返回 NaN,Number可以转换false,[],'',null 为0和 true 为1,注意js中数字0会转化成 false,字符串0则会转化成 true
toString() 把值转换成字符串,但 null 和 undefined 不能转换,String() 和+value 可以转换 null 和 undefined
拖拽事件
js拖拽时不能触发 onmouseup 事件,是因为触发了 js 原生的拖拽事件。并且不会监听到 onmouseup,解决方法干掉js的拖拽事件:
document.ondragstart = function(ev) {
ev.preventDefault()
}
document.ondragend = function(ev) {
ev.preventDefault()
}
指定范围随机整数
function randomNum(min,max){ return Math.floor(Math.random()*(max-min+1)+min)}
获取数组对象最高值
获取数组对象最高值:Math.max.apply(null, arr.map(function (o) {return o.num}))
循环
性能: for>forEach>for of>map>for in,return 有2个作用,结束函数和返回结果,forEach 使用 return 只是跳出了当前的循环,无法退出循环,返回结果, 使用 break 报语法错误
转义字符
空格在不同浏览器的距离不同,可使用 和 ,分别是占据的宽度正好是1/2个中文宽度和1个中文宽度
call/apply/bind
call/apply/bind 的核心理念:借用方法,借助已实现的方法,改变方法中数据的 this 指向,减少重复代码,节省内存
call和apply 方法改变 this 指向(函数执行时所在的作用域),然后在指定的作用域中,调用该函数。同时也会立即执行该函数,apply 参数为一个数组 array
js执行机制
先执行主线程,然后进入(宏任务)后,开始第一次循环,接着执行该宏任务所有的微任务。然后再次从下个宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务,一次只会执行一个宏任务
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick
setTimeout(()=>{
console.log('A');
},0)
let obj={
func:function () {
setTimeout(function () {
console.log('B')
},0)
return new Promise(function (resolve) {
console.log('C')
resolve()
})
}}
obj.func().then(function () {
console.log('D')
})
console.log('E')
// C E D A B
js拖拽原理
数组对象字段映射
function convertTree (tree, map) {
let result = [] // 遍历 tree
tree.forEach((item) => { // 读取 map 的键值映射
let value = item[ map.value ]
let label = item[ map.label ]
let children = item[ map.children ]
// 如果有子节点,递归
if (children) {
children = convertTree(children, map)
}
result.push({ value, label, children }) })
return result
}
扁平数据转成树形数据
function treeData(source){
let cloneData = JSON.parse(JSON.stringify(source)) // 对源数据深度克隆
return cloneData.filter(father=>{
let branchArr = cloneData.filter(child=>father._id == child.parentId)
//返回每一项的子级数组
branchArr.length>0 ? father.children = branchArr : ''
//如果存在子级,则给父级添加一个children属性,并赋值
return father.parentId=='0'; //返回第一层 }
)
}
合并相同对象的项并生成新数组
function handleData(arr){
let newData = []; // 目标数组
let newObj = {};
arr.forEach((item, index) => {
if (!newObj[item.month]) {
newData.push(item);
newObj[item.month] = true;
} else {
newData.forEach(data => {
if (data.month === item.month) {
data.articleArr = [...data.articleArr, ...item.articleArr]
}
})
}
})
return newData
}