JavaScript day009

58 阅读2分钟

*数组的API

一、排序:2种

1、冒泡排序

1、鄙视题:手写冒泡排序:从第一个元素开始,依次比较相邻的两个元素,如果前一个>后一个,两者就要交换位置
		公式:
		for(var j=1;j<arr.length;j++){
			for(var i=0;i<arr.length-j;i++){
				console.log(1);
				if(arr[i]>arr[i+1]){
					var m=arr[i];
					arr[i]=arr[i+1];
					arr[i+1]=m;
				}
			}
		}

2、正式开发中:数组提供的排序API:

arr.sort();

问题1:默认会将元素们转为字符串,按位PK每个字符unicode(ascii),如果希望按数字排序?

解决:
arr.sort(function(a,b){
//sort传了一个实参:比较奇怪,是一种匿名回调函数,不需要程序员自己调用,前辈们已经帮我们调好了,而且我们不需要管前辈们怎么创建的,只需要记忆固定用法即可
console.log(a);//后一个数字
console.log(b);//前一个数字
return a-b;//如果return 是一个正数:说明后一个数>前一个数
//如果return 是一个负数:说明后一个数<前一个数
//如果return 是一个0:说明后一个数==前一个数
//而sort方法会根据你return的正/负数,来自动进行排序操作
				})
				
问题2:希望降序排列

解决:
arr.sort(function(a,b){
return b-a;
			})

强调:排序非常重要,记住:只要以后页面中有排序功能,说明他的底层一定是一个数组,因为js中只有数组才可以排序

二、栈和队列:

	栈:其实就是数组,只不过要求是一段封闭,只能从另一端进出的数组
	何时:希望优先使用最新的数据时,现实生活中:电梯、旅游公交车...现实生活中少的,代码中用的也少
	如何使用:
		开头进:arr.unshift(新值1,...);//添加元素的新方式,缺陷:导致其余元素的下标发生变化
		开头出:var first=arr.shift();//一次只能删除一个,删除元素的新方式,可以接住你删除的元素,缺陷:导致其余元素的下标发生变化

		结尾进:arr.push(新值1,...);//添加元素的新方式
		结尾出:var last=arr.pop();//一次只能删除一个,删除元素的新方式,可以接住你删除的元素

	队列:其实就是数组,只不过要求是一端进,另一端出
	何时:希望按照先来后到的顺序使用数据时,生活中多个一批
		开头进:arr.unshift(新值1,...);
		结尾出:var last=arr.pop();

		结尾进:arr.push(新值1,...);
		开头出:var first=arr.shift();

ES3的数组API就到此告一段落了

*二维数组:数组的元素,又引用着另一个数组

何时:在一个数组内,希望再次细分每个分类
创建:
var arr=[
	["杨鑫",18,3500],
	["是新建",19,4500],
	["杨婷婷",20,5500]
];

访问:arr[行下标][列下标];
特殊:列下标越界,得到undefined
          行下标越界,会报错,因为只有数组才可以用[下标]。行下标越界已经得到undefined,没有资格再加下标

遍历二维数组:必然需要两层循环,外层循环控制行,内层循环控制列 - 现在都流行扁平化
	公式:for(var r=0;r<arr.length;r++){
			for(var c=0;c<arr[r].length;c++){
				console.log(arr[r][c])
			}
	          }

String的概念:

什么是字符串:多个字符组成的【只读】字符【数组】(只读:明天我们要学习的任何字符串API,都是不会修改原字符串,意味着必须要拿一个变量接住结果)
和数组有相同的点:
	1、字符串中个数(长度):str.length
	2、获取字符串中的某个字符:str[i];
	3、遍历字符串
	4、所有数组不修改原数组的API,字符串都可以使用(concat、slice)
	
和数组也有很多不同的地方:
	所有的数组直接修改原数组的API,字符串都不可以使用!比如排序只有数组可以使用,但是
	字符串也有很多很多属于自己的API

***引用/对象类型:11个
	*String Number Boolean -> 为什么这三个人即使原始类型又是引用类型?原因是他们三个具有包装类型?
	*Array *Function Date(日期) Math(数学) *RegExp(正则->表单的验证)
	Error(错误)
	*Object(面向对象开发方式)
	Global(全局对象) -> 特殊:再浏览器中没有globalwindow(全局对象:保存着全局变量和全局函数)给代替了,只不过window可以省略不写
			只有JavaScriptglobal才被代替为了window,而且node.js后端语言中!全局对象就叫global。

明天直接学习String API

*面试题(什么是包装类型)

***面试题:什么是包装类型?
	包装类型:专门将原始类型的值封装为一个引用类型的对象
	    为什么:原始类型的值原本是没有任何属性和方法的,意味着原始类型本身就是不支持.做操作的
		  但是前辈们发现字符串经常会被我们程序员所使用/操作
		  为了方便我们程序员为这三个人提供了包装类型,从值->对象(提供了很多属性和方法)
	何时使用:只要你试图用原始类型的变量去调用属性或方法时,自动包装
	何时释放:方法调用完毕后,包装类型就会自动释放,又变回了一个原始类型的值

	为什么undefinednull不能使用. - 没有包装类型

*轮播图(案例)

<body>
    <div class="carousel">
        <div class="car_img">
            <img class="active" src="../img/1.jpg" />
            <img src="../img/2.jpg" />
            <img src="../img/3.jpg" />
        </div>
        <img src="../img/3.jpg" />
        <button>1</button>
        <button>2</button>
        <ul>
            <li dy="0" class="active"></li>
            <li dy="1"></li>
            <li dy="2"></li>
        </ul>
    </div>
    <script>
        var btns = document.getElementsByTagName("button");
        var imgs = document.getElementsByTagName("img");//img有四个此时
        var lis = document.getElementsByTagName("li");
        var j = 0;//计算器:他的目的是需要记录下标 
        for (var i in btns) {
            btns[i].onclick = function () {
                if (this.innerText == "2") {
                    j++;
                    j == lis.length && (j = 0);//短路条件满足后执行操作,这样可以得到0.1.2的下标
                    //需要遍历i目的是清空
                    for (var i = 0; i < lis.length; i++) {
                        lis[i].className = "";
                        imgs[i].className = "";
                    }
                    imgs[j].className = "active";
                    lis[j].className = "active";
                } else {
                    //左边需要注意的是 我们要看到的是第三张图片 所有下边应该是从3开始到0结束 但是j--会减到-1
                    j--;
                    j == -1 && (j = lis.length - 1);
                    for (var i = 0; i < lis.length; i++) {
                        lis[i].className = "";
                        imgs[i].className = "";
                    }
                    imgs[j].className = "active";
                    lis[j].className = "active";
                }
            }
        }
        //小圆点其实可以吧它看作是一个选项卡 点击再显示
        //那么给小圆点开一个for in循环
        for (var i in lis) {
            //给lis绑定点击事件
            lis[i].onclick = function () {
                //我还需要去给html设置自定义下标dy=0 =1 =2然后得到自定义下标
                //为什么没有写var j=this.getAttribute("dy"); 这样会局部操作 全局已经定义好了j
                j = this.getAttribute("dy");
                //注意这里的操作其实和上面的左键右键是一样的都需要清空
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = "";
                    imgs[i].className = "";
                }
                imgs[j].className = "active";
                lis[j].className = "active";
            }
        }
        //此时添加定时器 
        timer = setInterval(function () {
            //只需要吧右边的操作cv过来即可 因为轮播都是从左往右才符合逻辑
            j++;
            j == lis.length && (j = 0);//短路条件满足后执行操作,这样可以得到0.1.2的下标
            //需要遍历i目的是清空
            for (var i = 0; i < lis.length; i++) {
                lis[i].className = "";
                imgs[i].className = "";
            }
            imgs[j].className = "active";
            lis[j].className = "active";
        }, 1000)
        div = document.getElementsByTagName("div")[0].onmouseover = function () {
            clearInterval(timer);
        }
        div = document.getElementsByTagName("div")[0].onmouseout = function () {
            timer = setInterval(function () {
                //只需要吧右边的操作cv过来即可 因为轮播都是从左往右才符合逻辑
                j++;
                j == lis.length && (j = 0);//短路条件满足后执行操作,这样可以得到0.1.2的下标
                //需要遍历i目的是清空
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = "";
                    imgs[i].className = "";
                }
                imgs[j].className = "active";
                lis[j].className = "active";
            }, 1000)
        }
    </script>
</body>