目录
JS数据类型的判断方法
var type = function(data) {
var toString = Object.prototype.toString;
var dataType = data instanceof Element
? 'element' // 为了统一DOM节点类型输出
: toString.call(data).replace(/\[object\s(.+)\]/, ''$1').toLowerCase();
return dataType;
}
类数组对象的遍历
var listMap = function (array, type, fn) {
return !fn ? array : Array.prototype[type]['call'](array, fn)
}
// 使用
var divs = document.querySelectorAll('div')
listMap(divs, 'forEach', function (e) {
console.log(e.innerHTML)
})
数组对象的去重
const data = [
{
name: 'Kris',
age: '24'
},
{
name: 'Andy',
age: '25'
},
{
name: 'Kitty',
age: '25'
},
{
name: 'Andy',
age: '25'
},
{
name: 'Kitty',
age: '25'
},
{
name: 'Andy',
age: '25'
},
{
name: 'Kitty',
age: '25'
}
]
const dataReducer = (prev, cur, idx) => {
let obj = {};
const { name } = cur;
obj[name] = cur;
return {
...prev,
...obj
}
}
const reducedData = data.reduce(dataReducer, {})
let newData = Object.values(reducedData)
console.log(newData)
/***输出结果***/
0: {name: "Kris", age: "24"}
1: {name: "Andy", age: "25"}
2: {name: "Kitty", age: "25"}
/**
* 涉及到的知识点:
*
* Object.keys获取对象属性, Object.values 获取对象的值
* reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
* 接收的函数可以有四个参数
* @param Object {prev} 前一个对象值,
* @param Object {cur} 当前对象值,
* @param Object {idx} 当前索引值,
* @param Array {arr} 数组对象,
* reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
*/
阻止事件默认行为和冒泡的兼容性写法
// 阻止冒泡
function stopPropagation(e){
if(e && e.stopPropagation){
e.stopPropagation()
}else{
window.event.cancelBubble = true;
}
}
// 阻止默认行为
function stopDefault(e){
if(e && e.preventDefault){
e.preventDefault();
}else{
window.event.returnValue = false;
}
}
为数字添加千位分隔符
function formatNumber(num) {
if (num) {
var reg = /^(\+|-)?(\d+)(\.\d+)?$/;
if (!reg.test(num)) {
return num;
}
var a = RegExp.$1,
b = RegExp.$2,
c = RegExp.$3;
var re = new RegExp("(\\d)(\\d{3})(,|$)");
while (re.test(b)) b = b.replace(re, "$1,$2$3");
return a + "" + b + "" + c;
} else {
return "0";
}
},
数字变化时滚动效果
引入插件:<script src="./digitroll.js"></script>
// 对变化的数据进行调用
<p class="numRoll" id="numRoll1"></p> 辆
var roll1 = new DigitRoll({
container: "#numRoll1"
});
// 数据变化产生滚动效果
roll1.roll(adata);
《digitroll.js》
/**
* H5数字滚动效果
* @class DigitRoll
* @desc 没有任何依赖, 只兼容webkit内核, 主要用于H5页面. 组件本身没有css, 如果需要修改默认样式 可以添加css样式修饰.
* @param {object} opts 实例化参数
* @param {string} opts.container 容器选择器 selector
* @param {number} opts.width=1 数字的总宽度个数, 即要显示几位数
* @example
HTML:
<div id="num-roll"></div>
* @example
js:
var r1=new DigitRoll({
container:'#happy-new-year',
width:9
});
*/
function DigitRoll(opts) {
this.container=document.querySelector(opts.container); //容器
this.width=opts.width || 1;
if (!this.container) {
throw Error('no container');
}
this.container.style.overflow='hidden';
this.rollHeight=parseInt(getComputedStyle(this.container).height); //容器高度 也用于滚动间隔距离
if (this.rollHeight<1) {//只有容器的高度是必选样式 如果没有设置 那就给一个默认的
this.container.style.height='20px';
this.rollHeight=20;
}
this.setWidth();
}
/** @lends DigitRoll */
DigitRoll.prototype={
/**
* 滚动数字
* @param {number} n 要滚动的数字 如:2015518518
* @example
r1.roll(2015518518);
//定时更新
setInterval(function(){
r1.roll(314159);
},5000)
*/
roll:function (n) {
var self=this;
this.number=parseInt(n)+'';
if (this.number.length<this.width) {
this.number=new Array(this.width - this.number.length + 1).join('0') + this.number;
}else if (this.number.length>this.width) {
this.width=this.number.length;
this.setWidth();
}
Array.prototype.forEach.call(this.container.querySelectorAll('.num'), function (item,i) {
var currentNum=parseInt(item.querySelector('div:last-child').innerHTML);//当前数字
var goalNum=parseInt(self.number[i]);//目标数字
var gapNum=0; //数字滚动的间隔个数
var gapStr='';
if (currentNum==goalNum) { //数字没变 不处理
return ;
}else if(currentNum<goalNum) { // 比如数字从1到3
gapNum=goalNum-currentNum;
for (var j=currentNum; j<goalNum+1; j++) {
gapStr+='<div>'+j+'</div>'
}
}else {// 比如 数字从6到5 因为所有情况都是从下往上滚动 所以如果是6到5的话 要滚动9个数字
gapNum=10-currentNum+goalNum;
for (var j=currentNum; j<10; j++) {
gapStr+='<div>'+j+'</div>'
}
for (var j=0; j<goalNum+1; j++) {
gapStr+='<div>'+j+'</div>'
}
}
item.style.cssText += '-webkit-transition-duration:0s;-webkit-transform:translateY(0)';//重置位置
item.innerHTML = gapStr;
setTimeout(function () {
item.style.cssText+='-webkit-transition-duration:1s;-webkit-transform:translateY(-'+self.rollHeight*gapNum+'px)';
},50)
})
},
/**
* 重置宽度
* @desc 一般用不到这个方法
* @param {number} n 宽度 即数字位数
* @example
r1.setWidth(10);
*/
setWidth:function (n) {
n=n||this.width;
var str='';
for (var i=0; i<n; i++) {
str+='<div class="num" style="float:left;height:100%;line-height:'+this.rollHeight+'px"><div>0</div></div>';
}
this.container.innerHTML=str;
}
}
集成判断数据是否为空
judgeNull(data) {
if (data) {
return data;
} else {
return " ";
}
},
逻辑判断条件为假的条件
0," "[空字符串],false,null,undefined,NaN
对字符串的拓展
console.log("***1.将字符串中的多个空格缩减为一个空格***")
String.prototype.ResetBlank = function () {
var regEx = /\s+/g;
return this.replace(regEx, '');
};
var str = "youkuaiyun.com is a good site";
console.log(str); // youkuaiyun.com is a good site
console.log(str.ResetBlank()); // youkuaiyun.com is a good site
console.log("***2.判断字符串是否为空,多个空格也算为空***")
String.prototype.trim = function () {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
function isEmpty(obj) {
if (typeof obj === "undefined" || obj == null || obj.trim() == "") {
console.log(true)
return true;
} else {
console.log(false)
return false;
}
}
isEmpty(" ") // true
isEmpty("1") // false
数组和字符串的相关操作
/**
* 数组
*/
// 数组对象的深拷贝
/**
* 循环数组中每个对象都复制(其实还是对象复制)
*/
for(let i=0;i<res.length;i++){
origData.push(Object.assign({}, res[i]))
}
/**
* 使用 JSON 方法
*/
origData = JSON.parse(JSON.stringify(res))
// 数组的深拷贝
var arr = [23,34,5,6,7]
var arr2 = arr.slice(0)
arr2[1] = 4
console.log(arr) // [23, 34, 5, 6, 7]
console.log(arr2) // [23, 4, 5, 6, 7]
/*
* 其他方法:
* arr.slice(0)、arr.concat()、
* ES6扩展运算符实现 var [ ...arr2 ] = arr
*/
// 返回数组中最大值的索引
var i = arr.indexOf(Math.max(...arr));
/**
* 字符串
*/
// 替换字符串中的某一字符
var str = "acdeaaa"
var str1 = str.replace("a", "*") // 替换遇到的第一个符合条件的字符
var str2 = str.replace(/a/g, "&") // 替换所有符合条件的字符
console.log(str) // acdeaaa // 不改变原字符串
console.log(str1) // *cdeaaa
console.log(str2) // &cde&&&
// 判断字符串中是否包含某个字符串
/**
* indexOf() 返回指定的字符串值在字符串中首次出现的位置。
* 如果要检索的字符串值没有出现,则该方法返回 -1。
*/
var str = "acdeadaa";
console.log(str.indexOf("d")) // 2
console.log(str.indexOf("d") != -1 ); // true
/*
* search()原理和indexOf()相似
*/
var str = "kicaadsa";
console.log(str.search("a")) // 3
console.log(str.search("a") != -1 ); // true
/**
* match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
*/
var str = "123";
var reg = RegExp(/3/);
if(str.match(reg)){
// 包含
}
关于正则表达式
Object.keys()或者for…in来枚举对象的属性名
Object.getOwnPropertyNames(obj) 获取元素属性
对象的拼接
Object.assign(a, b)
// 拼接后第一个拼接对象a 的值也会是拼接的值或者理解为把 b 的值合并到 a 中
Object.assign({},a, b) // 解决
遍历赋值法 和 $.extend([deep], obj1, obj2) 相同,将对象合并到第一个对象中。
// 代码逻辑:
// 1-循环对象n中的每一个对应属性。
// 2-确认对象n中存在该属性
// 3-确认对象o中不存在该属性
var extend=function(o,n){
for (var p in n){
if(n.hasOwnProperty(p) && (!o.hasOwnProperty(p) ))
o[p]=n[p];
}
};
数组的去重合并
参考链接 https://blog.youkuaiyun.com/weixin_40805079/article/details/84850745
深拷贝,浅拷贝【数组+数组对象】
深拷贝的核心思想就是将引用类型展开成基本类型,再进行拷贝。
数组中的每一项值必须是基本类型
数组:
浅拷贝
1- arr1.slice(); arr1.concat();
slice和concat这两个方法,仅适用于对不包含引用对象的一维数组的深拷贝
2- ES6 的展开符:[…arr1]
3-
arr1.forEach(item=>{
arr2.push(item)
});
4-
const _ = require('lodash');// 必须
arr2 = _.clone(arr1)
5- 通过遍历数组
function deepCopy(arry1, arry2){
var length = arry1.length;
for(var i = 0;i<length;i++){
arry2[i] = arry1[i];
}
}
deepCopy(arr1, arr2);
深拷贝对象数组:
// 方法一
let two_brand = one_brand.map(o => Object.assign({}, o));
// 方法二
let two_brand = one_brand.map(o => ({...o}));
// 方法三(推荐)
// 下载
npm i lodash --S
// 导入(哪个页面需要就在哪引入)
import _ from 'lodash' // 深拷贝
// 使用
let two_brand = _.cloneDeep(one_brand);
//(不推荐)
let two_brand = JSON.parse(JSON.stringify(one_brand))
主要缺点是,只限于处理可被 JSON.stringify() 编码的值。
JSON.stringify() 将编码 JSON 支持的值。包含 Boolean,Number,String,对象,数组。其他任何内容都将被特殊处理。
undefined,Function,Symbol 时,它被忽略掉
Infinity,NaN 会被变成 null
Date 对象会被转化为 String (默认调用date.toISOString())
// 拓展
问:为什么JSON.stringify() 编码 JSON 支持的值那么少呢?
因为JSON是一个通用的文本格式,和语言无关。设想如果将函数定义也stringify的话,如何判断是哪种语言,并且通过合适的方式将其呈现出来将会变得特别复杂。特别是和语言相关的一些特性,比如JavaScript中的Symbol。
判断是否是数组
参考链接 https://www.cnblogs.com/zhizhic/p/9988947.html
常见http请求错误提示
参考链接 https://blog.youkuaiyun.com/优快云_000000000000001/article/details/94341596
请求报504[服务器端错误,网页请求超时] / 405错误[请求方式错误]
400 表示语义有误,当前请求无法被服务器理解
505 HTTP协议不受支持
500 内部服务器错误
304 请求的网页与上次对比没有更新,不是错误,只是用了缓存的数据,不用下载了