JavaScript 数据操控的方式

75 阅读4分钟

执行上下文

1.首先将预编译和形参定义undefined

2.将形参和实参统一

3.将函数体定义声明

<script>     
    function A(){         
        var funs=[];         
        for(var i=0;i<10;i++){            
            funs[i]=function(){                
                return i;            
            }         
        }         
        return funs;      
    }     
    var funs = A();//定义funs[0]-funs[9],10个函数    
    console.log(funs[0]());//10     
    console.log(funs[1]());//10     
    console.log(funs[6]());//10 
</script>

当执行var funs = A();时,只是定义函数,而没有执行 真正产生环境变量的时间是在console.log(funs[0]()); 都为10 如果把var i=0改为let i=0;则打印出的结果是0 1 2 .。。。。

类型和数据操控

  • Object.values()和object.keys()一个返回值,一个返回key值
  • 字符填充(padStart()和padEnd()
'Vue'.padStart(10)           //'       Vue'
'Vue'.padEnd(10, '_*')           //'Vue_*_*_*_'
  • arguments
arguments.callee 调用自身正在执行的函数 用于计算乘阶4*3*2*1
arguments.callee.length获取函数要求传参的个数
arguments.callee.length获取函数要求传参的个数
  • arguments类数组 argument是一个对象,只不过它的属性从0开始排,依次为0,1,2...最后还有callee和length属性

常见的类数组还有:

用getElementByTagName/ClassName/Name()获得的HTMLCollection
用querySlector获得的nodeList
  • 类数组转换为数组
//Array.prototype.slice.call()
function sum(a, b) {
  let args = Array.prototype.slice.call(arguments);
  console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3

//Array.from() /Array.of
//array.from将对象转换为数组
//array.of(10,20,30)=>[10,20,30]
function sum(a, b) {
  let args = Array.from(arguments);
  console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3

//ES6展开运算符
function sum(a, b) {
  let args = [...arguments];
  console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3

//利用concat+apply
function sum(a, b) {
  let args = Array.prototype.concat.apply([], arguments);//apply方法会把第二个参数展开
  console.log(args.reduce((sum, cur) => sum + cur));//args可以调用数组原生的方法啦
}
sum(1, 2);//3
  • forEach中return有效果吗?如何中断forEach循环 在forEach中用return不会返回,函数会继续执行
let nums = [1, 2, 3];
nums.forEach((item, index) => {
  return;//无效
})

中断方式

  1. 使用try监视代码块,在需要中断的地方抛出异常。
  2. 官方推荐方法(替换方法):用every和some替代forEach函数。every在碰到return false的时候,中止循环。some在碰到return ture的时候,中止循环

JS判断数组中是否包含某个值

  • array.indexOf
  • array.includes(searcElement[,fromIndex])
    返回true和false
  • array.find(callback[,thisArg]) 返回数组中满足条件的第一个元素的值,如果没有,返回undefined
var arr=[1,2,3,4];
var result = arr.find(item =>{
    return item > 3
});
console.log(result);
  • array.findeIndex(callback[,thisArg]) 返回数组中满足条件的第一个元素的下标,如果没有找到,返回-1]
var arr=[1,2,3,4];
var result = arr.findIndex(item =>{
    return item > 3
});
console.log(result);

数组扁平化

多维数组=>一维数组

let ary = [1, [2, [3, [4, 5]]], 6];// -> [1, 2, 3, 4, 5, 6]
let str = JSON.stringify(ary);
  • 调用ES6中的flat方法
ary = arr.flat(Infinity);
  • replace + split
ary = str.replace(/(\[|\])/g, '').split(',')
  • replace + JSON.parse
str = str.replace(/(\[|\]))/g, '');
str = '[' + str + ']';
ary = JSON.parse(str);
  • 普通递归
let result = [];
let fn = function(ary) {
  for(let i = 0; i < ary.length; i++) {
    let item = ary[i];
    if (Array.isArray(ary[i])){
      fn(item);
    } else {
      result.push(item);
    }
  }
}
  • 利用reduce函数迭代
function flatten(ary) {
    return ary.reduce((pre, cur) => {
        return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
    }, []);
}
let ary = [1, 2, [3, 4], [5, [6, 7]]]
console.log(flatten(ary))
  • 扩展运算符
//只要有一个元素有数组,那么循环继续
while (ary.some(Array.isArray)) {
  ary = [].concat(...ary);
}

数组中的高阶函数

  • map 参数:接受两个参数,一个是回调函数,一个是回调函数的this值(可选)。 其中,回调函数被默认传入三个值,依次为当前元素、当前索引、整个数组。
let nums = [1, 2, 3];
let obj = {val: 5};
let newNums = nums.map(function(item,index,array) {
  return item + index + array[index] + this.val; 
  //对第一个元素,1 + 0 + 1 + 5 = 7
  //对第二个元素,2 + 1 + 2 + 5 = 10
  //对第三个元素,3 + 2 + 3 + 5 = 13
}, obj);
console.log(newNums);//[7, 10, 13]
  • sort 一个用于比较的函数,它有两个默认参数,分别是代表比较的两个元素
let nums = [2, 3, 1];
//两个比较的元素分别为a, b
nums.sort(function(a, b) {
  if(a > b) return 1;
  else if(a < b) return -1;
  else if(a == b) return 0;
})

当比较函数返回值大于0,则 a 在 b 的后面,即a的下标应该比b大。

反之,则 b 在 a 的后面,即 a 的下标比 b 小。

整个过程就完成了一次升序的排列。

当然还有一个需要注意的情况,就是比较函数不传的时候,是如何进行排序的?

答案是将数字转换为字符串,然后根据字母unicode值进行升序排序,也就是根据字符串的比较规则进行升序排序。

IEEE754

将一个二进制转换为合适为:V=(-1)s次方 M2 E次方 来进行浮点数表示 S决定正还是负 M二进制小数,范围12-e次方或者01-e次方