美文网首页
javascript工作零散杂记

javascript工作零散杂记

作者: squidbrother | 来源:发表于2021-01-17 08:51 被阅读0次
概述

javascript 操作 整理的乱七八糟

1.快速创建数据
let arr3 = new Array(5).fill(1).map((val,index)=>({name:('zhangsan'+index),age:(18+index)}));

[
    { name: "zhangsan0", age: 18 }
    { name: "zhangsan1", age: 19 }
    { name: "zhangsan2", age: 20 }
    { name: "zhangsan3", age: 21 }
    { name: "zhangsan4", age: 22 }
]

2.输出页面中所有使用过的标签种类有哪些,分别是什么?

var objs = Array.from(document.getElementsByTagName('*'));
var setArr = new Set(objs.map(val=>val.tagName));
console.log('有多少个标签: '+setArr.size);
var str = Array.from(setArr).join(',');
console.log('它们分别是: '+str);

3.将数组的每一项加+1,通过Array.from的第二个参数

var arr = [1,2,3,4];
var res = Array.from(arr,val=>val+1);
  1. 深拷贝、浅拷贝的区别与实现方式
  • 基本类型与引用类型
    基本类型:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
    引用类型:对象(Object)、数组(Array)、函数(Function)
    基本类型存在栈内是一个具体的值
    引用类型存在栈内是一个内存地址,通过这个地址找过去是一个堆(方便扩展,内存分配大小未知)

  • 深拷贝与浅拷贝的区别:
    由于javascript数据类型,有两种,一个是基本类型,一个是引用类型
    针对基本类型的拷贝是 深拷贝 (操作的数据,真实数据在内存的栈里)
    针对引用类型的拷贝是 浅拷贝 (操作的数据,真实数据在堆里,栈里只保存一个堆的地址)

  • 浅拷贝的实现:
    数组浅拷贝 方法1

var a1 = [12,{'a':1},47,56,213,4654,154];
var a2 = Array.from(a1);
a2[1].a = 2;
console.log(a1[1].a); //2

数组浅拷贝 方法2

var a1 = [12,{'a':1},47,56,213,4654,154];
var a2 = a1.slice(0);
a2[1].a = 2;
console.log(a1[1].a); //2
  • 深拷贝的实现:
    方式一:ES6新语法
JSON.parse(JSON.stringify(obj))

但是需要注意问题 ,数据中嵌套的值不能含有( new Date、RegExp、Error、函数,undefined、NaN、Infinity和-Infinity、实例 )

方式二:遍历方式

//commonTools.deepClone(obj)
let commonTools=(function(){
    function isArray(val) {
        return Object.prototype.toString.call(val) === '[object Array]';
    }
    function isObject(val) {
        return typeof val === 'object' && val !== null;
    }
    function doit(obj2) {
        var obj = isArray(obj2) ? [] : {};
        for (var property in obj2) {
             if (isObject(obj2[property])) {
                obj[property] = doit(obj2[property]);
            } else {
                obj[property] = obj2[property];
            }
        }
        return obj;
    }
    return {
      deepClone : doit
    }
})();
  1. 判断原型
Object.prototype.toString.call(new Date());   //"[object Date]"
Object.prototype.toString.call([1,2,34]);         //"[object Array]"

5-2. 调用不同类型特有的方法
如: 类数组 => 数组

var 新数组 = Array.prototype.slice.call(类数组);
  1. 简单防止copy,但是通过浏览器菜单内开发者工具,是可以跳过去的
document.onkeydown=function(){
    var e = window.event||arguments[0];
    if(e.keyCode==123){
        alert('请尊重劳动成果');
            return false;
    }else if((e.ctrlKey)&&(e.shiftKey)&&(e.keyCode==73)){
        alert('请尊重劳动成果!');
            return false;
    }else if((e.ctrlKey)&&(e.keyCode==85)){
            alert('请尊重劳动成果!');
            return false;
    }else if((e.ctrlKey)&&(e.keyCode==83)){
           alert('请尊重劳动成果!');
           return false;
    }
}
document.oncontextmenu=function(){
    alert('请尊重劳动成果!');
    return false;
}
  1. 一些简写
  • 浅拷贝
var newArr = arr1.slice(0);
  • 16位随机数
var num = 15;
var a = num.toString();  //--10进制
var b = num.toString(2);  //--2进制
var c = num.toString(8);  //--8进制
var d = num.toString(16);  //--16进制
Math.random().toString().substring(2, 15);
var keys= Object.keys(obj);
var values = Object.keys(obj).map(key => row[key]);
var values= Object.values(obj);

不支持ES6、兼容性( IE9-10 )

var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
  • 判断空对象 法1
JSON.stringify(object) == {}
  • 判断空对象 法2
function checkObj(obj) {
    for(var key in obj) {
        return false;
    }
    return true;
}
  1. 微信自动播放的生命周期(考古)
<audio controls="controls"> 
    <source src="music/bg.ogg" type="audio/ogg"></source>
    <source src="music/bg.mp3" type="audio/mpeg"></source>
    优先播放音乐bg.ogg,不支持在播放bg.mp3
</audio>

javascript

//微信下兼容处理
document.addEventListener("WeixinJSBridgeReady", function () {
    music.play();
}, false);
  1. stopPropagation针对主流浏览器,cancelBubble针对IE浏览器(现在也可以作用主流浏览器)
_btn1.onclick = function(ev){
    var oEv = ev || window.event;
    stopBubble(oEv);
    console.log(111);
};
//stopBubble
function stopBubble(oEv){
    if(oEv.stopPropagation){
        oEv.stopPropagation();
    }else{
        oEv.cancelBubble= true;
    };
}

第10条的修改 getPropertyPriority ----- 待完成!!!!!!!!!!!!!!!!!!

  1. 判断是否支持某些CSS属性
    判断支持css3某些属性
function supportCss3(style){
    var prefix = ['webkit','Moz','ms','o'],i,humpString = [],htmlStyle = document.documentElement.style,_toHumb = function(string){
    return string.replace(/-(\w)/g,function ($0,$1){
        return $1.toUpperCase();
    });};
    for(i in prefix) 
    humpString.push(_toHumb(prefix[i] + '-' + style));
    humpString.push(_toHumb(style));
    for (i in humpString) 
    if (humpString[i] in htmlStyle) return true;
    return false;
}
  • 设置css3
function css3(obj, attr, val) {
    var str = attr.charAt(0).toUpperCase() + attr.substring(1);
    obj.style['Webkit' + str] = val;
    obj.style['Moz' + str] = val;
    obj.style['ms' + str] = val;
    obj.style['O' + str] = val;
    obj.style[attr] = val;
}
//使用
css3(somedom, 'transform', 'scale(' + _tc + ')');
  1. 浏览器是否支持某标签
    如:音频audio标签
!!document.createElement('video').play;
'play' in document.createElement('video');
  1. 判断两个点的夹角与距离
//判断两个点夹角
function getAngle(p1, p2) {
    var x = p1.pageX - p2.pageX,
        y = p1.pageY - p2.pageY;
    return Math.atan2(y, x) * 180 / Math.PI;
};
//两点距离
function getDistance(p1, p2) {
    var x = p2.pageX - p1.pageX,
        y = p2.pageY - p1.pageY;
    return Math.sqrt((x * x) + (y * y));
}
  1. 获取一个范围的随机值
function randomRange(myMin, myMax) {
  return Math.floor(Math.random()*(myMax - myMin+1)) + myMin; 
}
  1. 一个元素的抖动
function shake(obj, attr, endFn) {
    var arr = [];
    var timer = null;
    var n = 0;
    if (!obj.num) {
        obj.num = parseFloat(getComputedStyle(obj)[attr]);
    }
    //拿到一组数字,抖动的幅度。
    for (var i = 20; i > 0; i -= 2) {
        arr.push(i, -i);
    }
    arr.push(0);
    //用定时器来实现抖动效果。
    clearInterval(timer);
    timer = setInterval(function () {
        n++;
        if (n > arr.length - 1) {
            clearInterval(timer);
            endFn && endFn();
        }
        obj.style[attr] = arr[n] + obj.num + 'px';
    }, 30);
}
  1. 判断是否为一个数字 ( isFinite兼容IE4+,判断是否为一个有限数字)
function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}
  1. 数组最大值最小值,传递一个数组 (Math.max兼容IE3+)
var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; 
var maxInNumbers = Math.max.apply(Math, numbers); 
var minInNumbers = Math.min.apply(Math, numbers);
  1. 宏任务、微任务


    事件执行顺序

    执行顺序, 同步任务 > 微任务 > 宏任务
    同步任务: promise的逻辑部分
    宏任务: setTimeout、setInterval
    微任务: promise的then

  2. 箭头函数与普通函数的区别
    a. 二者的书写方式( 缩写方式也 )不用,箭头函数表现的更加简洁
    b. 箭头函数中的this,为其上下文中的this,或者说箭头函数没有自己的this
    c. 箭头函数不能作为构造函数使用,不能使用new,( 因为函数没有自己的this )
    d. 箭头函数没有自己的arguments ( arguments实际上获得的是外层局部(函数)执行环境中的值 )
    e. call、apply、bind 并不会影响其 this 的指向
    f. 箭头函数没有原型prototype、箭头函数不能当作 Generator 函数,不能使用 yield 关键字

数据类型 相关

  1. 基本数据类型和引用数据类型的区别
  • 基本数据类型不可以添加属性和方法、引用类型可以添加属性和方法
  • 基本数据类型的赋值是简单赋值、引用类型的赋值是对象引用(即声明的变量标识符,存储的只是对象的指针地址)
  • 基本数据类型是存放在栈区的、引用类型在栈里存的是一个内存地址,所在地址的内容在堆中( 引用类型是同时保存在栈区和堆区中的,栈区保存变量标识符和指向堆内存的地址 )
  • 基本数据类型的比较是值的比较、引用类型的比较是引用(指针地址)的比较

promise相关

  1. async await 是怎么解析的

async await是一个语法糖,
async理解为函数返回一个promise,
await理解为后面函数.then

例如:

async function fn1(){
  let data1 = await ajaxFn('xxx');
  console.log(1);
  return 100;
}
  • await 删除await,await后面的代码都放在一个then的处理函数中,await之前接收的变量放在then的参数中
    会被解析为
async function fn1(){
  ajaxFn('xxx').then(data1=>{
    console.log(1);
    return 100;
  });
}
  • async会被解析为一个新的Promise
function fn1(){
return new Promise((reslove,reject)=>{
  ajaxFn('xxx').then(data1=>{
    console.log(1);
    reslove(100);
  });
});
  1. async await对比promise的优缺点
  • async/await优点:
    a. 它做到了真正的串行的同步写法,代码阅读相对容易
    b. 对于条件语句和其他流程语句比较友好,可以直接写到判断条件里面
    c. 处理复杂流程时,在代码清晰度方面有优势

  • async/await缺点:
    a. 无法处理promise返回的reject对象,要借助try...catch...
    b. 用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,代码失去了并发性
    c. try...catch...内部的变量无法传递给下一个try...catch...,只能在外层作用域先定义好。

  • promise的一些问题:
    a. 一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来
    b. 错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
    c. Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

数组扁平化

  1. ES6语法
arr.flat(Infinity);
  1. 通过正则删除数组前后符号'['与']'
JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']');
  1. Array.isArray() 与 Array.prototype.reduce 兼容均为IE9+
const flatten = arr => {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
  }, [])
}
const res4 = flatten(arr);
  1. 函数递归
const res5 = [];
const fn = arr => {
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      fn(arr[i]);
    } else {
      res5.push(arr[i]);
    }
  }
}
fn(arr);

数组去重

  1. 利用ES6 Set特性
const res1 = Array.from(new Set(arr));
  1. 遍历数组去重
    res.indexOf(arr[i]) === -1!res.includes(arr[i])
const unique2 = arr => {
  const res = [];
  for (let i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) === -1) res.push(arr[i]);
  }
  return res;
}
  1. 通过Map来做去重标记
var arr = [1, 2, 1, 5, 6, 5];
const unique5 = arr => {
    const map = new Map();
    const res = [];
    for (let i = 0; i < arr.length; i++) {
        if (!map.has(arr[i])) {
            map.set(arr[i], true)
            res.push(arr[i]);
        }
    }
    return res;
};
console.log(unique5(arr));

数组常用方法

  1. map()
    return 是针对item的处理
    map() 数组方法的行为就像一个纯函数,不会改变原始数组

  2. filter()
    return 是一个条件,返回符合条件的item
    filter() 函数行为就像一个纯函数,不会改变原始数组

  3. find()
    return 是一个条件,返回符合条件的item
    find() 数组方法用于在数组中查找给定对象

  4. forEach()
    遍历数组

  5. some()
    return 一个条件,某一个遍历项符合条件,就返回true
    some函数行为就像一个纯函数,不会改变原始数组

  6. every()
    return 一个条件,每一个遍历项都符合条件,才返回true
    every函数行为就像一个纯函数,不会改变原始数组

  7. reduce()
    遍历数组
    array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
    total - 必需。初始值, 或者计算结束后的返回值。
    currentValue - 必需。当前元素
    currentIndex - 可选。当前元素的索引
    arr - 可选。当前元素所属的数组对象。
    initialValue - 可选。传递给函数的初始值

  8. includes() (兼容IE14+)
    数组内是否包含某项(第二个参数可选,某个索引位置)
    arr.includes(searchElement, fromIndex)

防抖与节流

  • 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
    应用场景: 类似百度框的搜索输入
const debounce = (fn, time) => {
  let timeout = null;
  return function() {
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      fn.apply(this, arguments);
    }, time);
  }
};
  • 高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。
const throttle = (fn, time) => {
  let flag = true;
  return function() {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, arguments);
      flag = true;
    }, time);
  }
}

未完待续....

相关文章

  • javascript工作零散杂记

    概述 javascript 操作 整理的乱七八糟 1.快速创建数据let arr3 = new Array(5)....

  • 零散杂记

    UIlabel 遇到\n 换行-iOS NSString *msg; msg= [NSString stringW...

  • javascript杂记

    title: javascript杂记date: 2017-05-21 14:34:25tags: javascr...

  • javascript 杂记

    数组杂记 1)数组的判断,使用Array.isArray() 2)一维数组的深拷贝 3)多维数组的深拷贝 4)数组...

  • javascript杂记

    1 2 3 onblur 失去焦点onkeypress:某个键盘的键被按下或按住测试测试结果:keypress 键...

  • 2019-01-24

    读 javascript 忍者秘籍 本文是作者阅读 javascript 忍者秘籍这本书过程中所记录零散知识和学习...

  • JavaScript零零散散

    一些优雅的写法逻辑运算符if (a == 1) { b()}// 可以写成a == 1 && b()if (co...

  • JavaScript杂记(3)

    1 对象 (无序的数据集) 由若干个“键值对”(key-value)构成。 var a={name:xxx}...

  • 散落乡间的古

    2012-07-15 22:5354零散杂记 小时候是听着老辈人访古度过的,那时的古是老人嘴里永也讲不完的故事。故...

  • 好好做自己,惊艳时光

    整理抽屉时,翻出了去年的日记。 说它是日记,更多的是像个杂记,或者说收账更准确些。 上面,零零散散的记着做过的事,...

网友评论

      本文标题:javascript工作零散杂记

      本文链接:https://www.haomeiwen.com/subject/cxkjoctx.html