项目中遇到的JS 基础知识小结

这篇博客总结了JavaScript中的一些基础知识和实用技巧,包括数据类型的判断、类数组对象的遍历、数组去重方法、阻止事件默认行为和冒泡、数字格式化、对象和数组的操作,以及深拷贝和浅拷贝的区别。还涵盖了HTTP请求错误提示和如何判断一个值是否为数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>&nbsp;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 请求的网页与上次对比没有更新,不是错误,只是用了缓存的数据,不用下载了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值