day0322

day0322

递归

递归的执行

函数在没有完全执行结束时,内部的所有变量都不会被销毁

递归会建立一个函数的副本,在堆中建立相同的函数引用,递归时调用这个函数引用

var i=0;
function fn1(){
    var a=3;
    i++;
   if(i<3) fn2();
   console.log(i);//最后打印的
}

function fn2(){
    var a=3;
    i++;
   if(i<3) fn3();
   console.log(i);//第二个被打印的
}

function fn3(){
    var a=3;
    i++;
   console.log(i);//最先打印的
}

fn1();

在这里插入图片描述

用递归遍历链表

var obj={value:1,next:{value:2,next:{value:3,next:{value:4,next:{value:5,next:null}}}}};

function fn1(obj){
    console.log(obj.value);
    if(obj.next) fn1(obj.next);
}

fn1(obj);

在这里插入图片描述

遍历对象

//创建对象
var obj = {
        a1: 1,
        b1: 2,
        c1: 3,
        d1: {
          a2: 4,
          b2: 5,
          c2: 6,
          e2: {
            a4: 7,
            b4: 8,
            c4: 9,
            d5: {},
          },
          d2: {
            a3: 10,
            b3: 11,
            c3: 12,
            f3: {
              a4: 13,
              b4: 14,
              c4: 15,
              d5: {},
            },
            d3: {
              a4: 16,
              b4: 17,
              c4: 18,
              d5: {},
            },
          },
        },
      };
深查找

递归查找对象中属性值符合要求的属性

function fn3(o,value){
    for(var prop in o){
        if(o[prop]===value) return prop;
        if(typeof o[prop]==="object" && o[prop]!==null){
            var s=fn3(o[prop],value)
            if(s) return s;
        }
    }
}

var prop=fn3(obj,14);
console.log(prop);

在这里插入图片描述

广度遍历 深度遍历

对象的广度遍历使用for in
对象的深度遍历使用递归

function fn1(obj){
    for(var prop in obj){
        console.log(prop,obj[prop]);
        if(typeof obj[prop]==="object" && obj[prop]!==null) 
         fn1(obj[prop])
    }
}

fn1(obj);

在这里插入图片描述

对象深复制 简单版

function fn1(source,target){
 if(target===undefined) target={};
   for(var prop in source){
       if(typeof source[prop]==="object" && source[prop]!==null){
         target[prop]={};
         fn1(source[prop],target[prop])
       }
       else {
         target[prop]=source[prop];
       }
   }
   return target;
}

var o=fn1(obj);

console.log(obj)
console.log(o);
console.log(obj==o);

在这里插入图片描述

二叉树遍历

js没有二叉树,所以要自己重构

//创建二叉树
var obj={
    value:0,
    left:{
        value:1,
        left:{
            value:3,
        },
        right:{
            value:4,
        }
    },
    right:{
        value:2,
        left:{
            value:5,
        },
        right:{
            value:6,
        }
    }
}
先序遍历

根左右

function fn1(o){//先序遍历 根左右
    console.log(o.value);
    if(o.left) fn1(o.left);
    if(o.right) fn1(o.right);
}

fn1(obj);

在这里插入图片描述

中序遍历

左根右

function fn2(o){//中序遍历  左根右
   	if(o.left) fn2(o.left);
    console.log(o.value);
    if(o.right) fn2(o.right);
}

fn2(obj);

在这里插入图片描述

后序遍历

左右根

function fn3(o){//后序遍历  左右根
   	if(o.left) fn3(o.left);
    if(o.right) fn3(o.right);
    console.log(o.value);
}

fn3(obj);

在这里插入图片描述

return在递归中的变化

十进制转二进制
function fn1(n, str) {
       if (str === undefined) str = "";
       str = (n % 2) + str;
       n = parseInt(n / 2); //7
       if (n) return fn1(n, str);
       return str;
     }
   console.log(fn1(26));

在这里插入图片描述

十进制转十六进制
function fn1(n,str){
    if(str===undefined) str="";
    n%16>9?str=String.fromCharCode(87+n%16)+str:str=n%16+str;
    n=parseInt(n/16);
    if(n) return fn1(n,str);
    return str;
}
console.log(fn1(26));

在这里插入图片描述

递归实现反向排序
//得到新的字符串,原字符串不变
function text_reverse(str,str_length,new_str){
     if(str_length===undefined) str_length=str.length;
     if(new_str===undefined) new_str="";
     return str_length==0?new_str:text_reverse(str,--str_length,(new_str+=str[str_length]))
}

字符串的length为只读属性

var str="abcde";
console.log(str.length);//字符串的length为只读属性
str.length--;//无效果
console.log(str.length);
console.log(str[str.length-1]);//通过下标访问字符串元素


var new_str=text_reverse(str);
console.log(str);
console.log(new_str);

在这里插入图片描述

body标签下子元素

document.body
document.body.children.length

数组

数组是一个列表,有序列表

引用类型对象

js中数组的元素可以类型不同,但建议保持类型相同

起始0

var arr=[3,4,5,10];
console.log(arr[0]);

在这里插入图片描述
数组实际上是按照下标存储元素的方式,将值存在列表中
下标 arr[1] 元素存储的位置 1就是下标
元素 arr[1]—>4 arr[1]下标变量 4就是元素

数组的创建

1.字面量创建
var arr=[1,2,3];

因为空元素就是下标没有对应的值,所以可以通过 下标 in 数组 这种方式判断

空元素与undefined的区别:

var arr=[1,,3,undefined,5];//中间有个空元素

for(var i=0;i<5;i++){
   if(!(i in arr))continue;
    console.log(arr[i]);
}

在这里插入图片描述

2.构造函数创建
var arr=new Array(1,2,3,4);
var arr=Array(1,2,3,4);

两种方法相同,之后讲怎么相同

如果构造函数中的元素数量大于1个,则所有的元素都是这个数组的元素

构造函数中的参数只有一个时,这个一个就是数组的长度

var arr=new Array(5);//相当于arr=[,,,,]
console.log(arr);

在这里插入图片描述

如果仅有一个参数,并且这个参数时数值类型,但是并不是正整数,就会报错

var arr=new Array(3.4);

在这里插入图片描述

var arr=new Array(-4);

在这里插入图片描述
如果仅有一个参数,但是这个参数不是数值类型,则会将这个参数放在数组的第0位

var arr=new Array("a");
console.log(arr);

在这里插入图片描述

3.对象创建
var arr=new Object([1,2,3,4]);

console.log(arr);

在这里插入图片描述
没什么用

数组长度

数组有length属性:有值或者空元素的数量

字符串有length属性,只读

对象无length属性

var arr=[11,21,31,41,51];
console.log(arr.length);

console.log(arr[arr.length-1]);
arr[30]=10;
console.log(arr);
console.log(arr.length);

在这里插入图片描述

var arr=[4,5,8,2,1];
for(var i=0;i<11;i++){
    //  arr[i]=i;//如果这样写会覆盖原来的元素
    arr[arr.length]=i;
}
console.log(arr);

在这里插入图片描述

arr.length是一个可读可写的属性

如果当前数组的长度小于设置的长度,则增加(新长度-原长度)数量的元素

var arr=[];
arr.length=5;//如果当前数组的长度小于设置的长度,则增加(新长度-原长度)数量的元素
console.log(arr);

在这里插入图片描述
如果新长度小于原长度,就会从后面删除(原长度-新长度)数量的元素

var arr=[1,2,4,5];
arr.length=2;//如果新长度小于原长度,就会从后面删除(原长度-新长度)数量的元素
console.log(arr);

在这里插入图片描述

清空数组

最好的方法:arr.length=0;

var arr=[1,2,4,5];
arr.length=0;//清空数组  最好的方法
console.log(arr);

在这里插入图片描述

用length删除尾部的最后一个元素

arr.length–;

var arr=[1,2,4,5];
arr.length--;//删除尾部的最后一个元素
console.log(arr);

在这里插入图片描述

length需要是正整数(0是清空数组)
var arr=[1,2,4,5];
arr.length-=5;//报错,length不能小于0或者是负数
console.log(arr);

在这里插入图片描述

var arr=[1,2,4,5];
arr.length="a";//报错,必须是一个正整数
console.log(arr);

在这里插入图片描述

复制数组
var arr=[1,2,3,4];
var arr1=arr;//这样复制的是引用地址

arr[2]=10;
console.log(arr1);

在这里插入图片描述

var arr=[1,2,3,4];
var arr1=[];
//for in 遍历复制值
for(var i=0;i<arr.length;i++){
    arr1[i]=arr[i];
}
arr[0]=10;
console.log(arr1);

在这里插入图片描述

数组中可存储:
var arr=["a","b","c"];
var arr=[true,false];
var arr=[{a:1,b:2},{c:3,d:4}];//对象型数组
var arr=[[1,2,3],[4,5,6]];//二维数组
var arr=[function(){
    console.log("aaa");
},function(){
    console.log("bbb");
}]
// 函数数组

数组的对象方法:

针对一个实例

push

尾部添加一个或者多个元素,并且返回数组的新长度

在这里插入图片描述

var arr=[];
var i=0;
while(arr.push(i++)<10);
console.log(arr);

在这里插入图片描述

var arr=[];
var len=arr.push(1);//len为此时数组的新长度
console.log(len);
arr.push(1,2,3);
console.log(arr);

在这里插入图片描述

重构:

function array_push(arr:Array){
//:Array表示arr的数据类型为了显示代码提示,运行之前需要删掉
		if(arr==undefined || arr.constructor!==Array) throw new Error("错误参数");
//throw new Error() 抛出错误 中断后续代码的执行
		if(arguments.length===1) return arr.length;
		for(var i=1;i<arguments.length;i++){
		   arr[arr.length]=arguments[i];
		}
// 给数组尾部一旦添加元素,arr.length就会自动重设
		return arr.length;
}
var arr=[];
var len=array_push(arr,3,4,6,2,1);
console.log(len,arr);

在这里插入图片描述

pop

删除数组尾部的一个元素,并且返回被删除的元素
在这里插入图片描述

var arr=[4,3,2,1];
var item=arr.pop();
console.log(item,arr);

在这里插入图片描述

重构:

function array_pop(arr){
    var item=arr[arr.length-1];
    arr.length--
    return item;
}
var arr=[4,3,2,1];
var item=array_pop(arr);
console.log(arr,item);

在这里插入图片描述

shift

删除数组头部的一个元素,并且返回被删除的元素

在这里插入图片描述

var arr = [1, 2, 3, 4];
var item=arr.shift();
console.log(item,arr);

在这里插入图片描述

重构:

function array_shift(arr){
if(arr.length===0) return;
var item=arr[0];
for(var i=0;i<arr.length-1;i++){
    arr[i]=arr[i+1];
}
arr.length--;
return item;
var arr = [1, 2, 3, 4];
var item=array_shift(arr);
console.log(item,arr);

在这里插入图片描述

unshift

英文:数组头部插入,首插入

向数组的头部添加一个元素或者多个元素,并且返回数组的新长度

在这里插入图片描述

var arr=[1,2,3];
var len=arr.unshift(0);
console.log(len,arr);

在这里插入图片描述

重构:

function array_unshift(arr) {
	if (arr == undefined || arr.constructor !== Array)
	  throw new Error("错误参数");
	if (arguments.length === 1) return arr.length;
	var len = arguments.length - 1; //当前添加参数数量
	arr.length = len = len + arr.length; //添加元素后数组的新长度
	while (len > 0) {
	  if (len > arguments.length - 1) {
	    arr[len - 1] = arr[len - arguments.length];
	  } else {
	    arr[len - 1] = arguments[len];
	  }
	  len--;
	}
	return arr.length;
}
var arr = [1, 2, 3, 4];
array_unshift(arr, 0,1,23,5);
console.log(arr);

在这里插入图片描述

concat

英文:合并数组,函数,合并多个字符串

合并数组,可以将一个数组和另外一个数组合并成一个数组,合并成的是新数组,原数组不变

可以用一个数组合并多个元素,产生一个新数组

如果不填写参数,则复制原数组,产生一个新数组

在这里插入图片描述

var arr=[1,2,3,4];
var arr1=arr.concat([5,6]);
console.log(arr1);

在这里插入图片描述
用concat复制数组

var arr=[1,2,3,4];
var arr1=arr.concat();
arr[0]=10;
console.log(arr);
console.log(arr1);

在这里插入图片描述

var arr=[1,2,3,4];
var arr1=arr.concat(4,5,[1,2,3],6)
console.log(arr1);

在这里插入图片描述

重构:

function array_concat(arr){
      if(arr==undefined || arr.constructor!==Array) throw new Error("不是一个数组");
      var arr1=[];
      for(var i=0;i<arr.length;i++){
          arr1[i]=arr[i];
      }
      if(arguments.length===1) return arr1;
      for(var j=1;j<arguments.length;j++){
          if(arguments[j] && arguments[j].constructor===Array){
              for(var k=0;k<arguments[j].length;k++){
                  arr1[arr1.length]=arguments[j][k];
              }
          }else
          arr1[arr1.length]=arguments[j];
      }
      return arr1;
  }
var arr=[1,2,3,4];
var arr1=array_concat(arr);
arr[0]=100;
console.log(arr);
console.log(arr1);

在这里插入图片描述

join

英文:连接,结合

连接字符串,用符号连接数组的元素并且生成字符串

在这里插入图片描述

var arr=[1,2,3,4];
var str=arr.join();
var str=arr.join("#");//除了undefined,都隐式转换为字符串
console.log(str);

在这里插入图片描述

重构:

function array_join(arr,separator){
      if(arr==undefined || arr.constructor!==Array) throw new Error("不是一个数组");
      if(separator===undefined) separator=",";
      separator=String(separator);
      var str="";
      for(var i=0;i<arr.length-1;i++){
          str+=arr[i]+separator;
      }
      str+=arr[arr.length-1];
      return str;
  }
var arr=[1,2,3,4];
var str=array_join(arr,"");
console.log(str);

在这里插入图片描述

fill

英文:(使)充满,填满

fill() 方法用于将一个固定值替换数组的元素
在这里插入图片描述

var arr=[];
arr.length=10;
arr.fill(1);
console.log(arr);

在这里插入图片描述
相当于

var arr=Array(10).fill(1);
console.log(arr);

在这里插入图片描述
起2止5

var arr=Array(10).fill(1,2,5);//起2止5
console.log(arr);

在这里插入图片描述

重构:

function array_fill(arr,item,start,end){
       if(arr==undefined || arr.constructor!==Array) throw new Error("不是一个数组");
       if(start===undefined) start=0;
       if(end===undefined) end=arr.length;
       for(var i=start;i<end;i++){
           arr[i]=item;
       }
       return arr;
   }
var arr=Array(10);
arr=array_fill(arr,1,2,5);
console.log(arr);

在这里插入图片描述

随机颜色
var color="#"+Array(6).fill(1).map(item=>parseInt(Math.random()*16).toString(16)).join("");
onsole.log(color);

每次刷新结果都不一样
在这里插入图片描述

静态方法:

针对类型

Array.from

将一个列表转换为数组

两个条件:

  1. 下标有0,1,2,3,4
  2. 必须要有length
    在这里插入图片描述

在这里插入图片描述

function fn1(){
//    var str= arguments.join("");//报错:arguments没有join方法
//    console.log(str);
		var arr=Array.from(arguments);
		var str=arr.join("");
		console.log(str);
}

fn1(1,2,3,4);

有下标有length属性的对象也可用Array.from转换为数组

var o={0:0,"1":1,"2":2,length:3};
console.log(Array.from(o));

在这里插入图片描述

重构:

Array.from_1=function(list){
      var arr=[]
      if(!list.length) return arr;
      for(var i=0;i<list.length;i++){
          arr[i]=list[i];
      }
      return arr;
}

简便写法 强记 之后再讲

return Array.prototype.slice.apply(list);
return Array.prototype.slice.call(list);
return [].slice.apply(list);
return [].slice.call(list);
return  [].concat.apply([],list);
return  Array.prototype.concat.apply([],list);
var o={0:0,"1":1,"2":2,length:3};
    console.log(Array.from_1(o));

function fn1() {
    var arr = Array.from_1(arguments);
    var str = arr.join("");
    console.log(str);
}
    fn1(1,2,3,4);

在这里插入图片描述

Array.isArray

判断元素是否是数组

console.log( Array.isArray([1,2]));
console.log( Array.isArray({a:1,b:2}));
console.log( Array.isArray({0:0,1:1,2:2,length:3}));

在这里插入图片描述

重构:

Array.isArray_1=function(list){
    return (list && list.constructor===Array) ? true :false
}
console.log(Array.isArray_1([1,2,3])) 
console.log(Array.isArray_1({a:1,b:2})) 
console.log(Array.isArray_1(null)); 

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值