js二阶段笔记

120 阅读7分钟

第二阶段js第一周笔记

day1

一、js概念-运行在浏览器端的解释型弱类型面向对象的脚本语言。

解释型:比较随意。碰到错误就停止。 弱类型:变量可以保存一切数据类型,由数据决定了数据类型是什么。

二、输出方式:

1、在控制台输出:console.log();
2、在页面上输出:document.write();
3、在警告框输出:alert();
用户输入框:var 保存=prompt("提示文字");

三、变量和常量:

var 变量名=值;const 常量名=值;

四、数据类型:

1、原始、基本、值类型: +Number/String/Boolean/Undefined/Null; 2、引用/对象类型:11个对象有很多很多的属性方法等待我们以后学习。 xx.xx; xx.xx();

五、运算符:

1.算术运算

注意:NaN:Not A Number,不是一个数字,他确实是数字类型,不在三界之中,不是一个有效的数字 全是缺点: 1、参与任何算术运算结果仍为NaN 2、参与任何比较运算结果都是false

2比较/关系:> < >= <= == != === !==

注意:布尔值 1、隐式转换:默认左右两边转为数字,再比较,如果参与比较的左右两边都是字符串的时候,按位PK每个字符串unicode号(ascii码) 数字<大写<小写<汉字 汉字的第一个字:一 - 4e00(19968) 龥 - 9fa5(40869) 2、参与任何比较运算结果都是false,我们不能使用普通的比较运算去判断x是不是NaN,解决: var bool=!isNaN(x); true=>是一个有效数字;false=>是一个NaN 3、undefined==null;//true 解决:undefined===null ===:全等:数值相同并且数据类型也要相同,不在带有隐式转换了 4、赋值运算、逻辑运算、自增和自减 其中: 单独使用,前++和后++没有区别 但是如果参与了别的表达式,变量中的值都会+1,返回不同 前++,返回的是新值 后++,返回的是旧值 var i = 1 var g = i++ + ++i + i++ + ++i; console.log(i) 5 console.log(g) 12

day2

1.分支结构

1、顺序结构 - 默认:从上向下依次执行每一句话 2、分支结构 - 通过条件判断,选择部分代码执行 3、循环结构 - 通过条件判断,选择要不要重复执行某块代码

if....else

1、else...if这句话想写多少,由程序员自己决定 2、else这句话可以省略不写,但是不推荐,如果不写,条件都不满足的情况,则什么事儿都不会发生 3、分支走了一条路,就不会再走别的路 让用户输入他的工资,计算应缴纳的税为多少 var user = prompt('请输入你的工资')

    if (!isNaN(user)) {
        var s = 0;
        if (user > 10000) {
            s += (user - 10000) * 0.1;
            user = 10000;
        }
        if (user > 5000) {
            s += (user - 5000) * 0.05;
            user = 5000;
        }
        if (user > 3500) {
            s += (user - 3500) * 0.025;
            user = 3500;
        }
        console.log('您应纳税额为:' + s);
    } else {
        console.log('请不要恶意输入')
    }

2、switch...case 分支

特殊:问题:默认只要一个case满足后,会将后续所有的操作全部做完 解决:break; 建议:每一个case的操作后面都跟上一个break 有的地方也可以不加break: 1、最后一个操作default可以省略break 2、如果中间多个条件,做的操作是一样的,可以省略掉中间部分 2、case在做比较的时候是不带有隐式转换的 3、default可以省略不写的,但是不推荐,如果不写,条件都不满足的情况,则什么事儿都不会发生 模拟10086的查询:

   var user = prompt('欢迎您使用10086:\n1.话费查询\n2.查询流量\n3.查询套餐\n4.转接人工');
    switch (user) {
        case "1":
            console.log('正在话费查询...')
            break;
        case '2':
            console.log('正在查询流量')
            break;
        case '3':
            console.log('正在查询套餐')
            break;
        case '3':
            console.log('正在转接人工')
            break;
        default:
            console.log('暂无此功能')
    }
    
面试题:if vs switch的区别?

1、switch...case:优点:执行效率较高,速度快(他比较时,case做的不是范围查找,而是等值比较) 缺点:必须要知道最后的结果是什么才可以使用 2、if...else...: 优点:可以做范围判断 缺点:执行效率较慢,速度慢(他做的是范围查找)

*****页面上一切数据js获取到后都是字符串类型

强制(显示)数据类型转换:

转字符串:2种方法

1、var str=x.toString();//x不能undefined和null,会报错,undefined和null不能使用.做任何操作,因为他们不是对象 2、var str=String(x);//万能的,任何人都可以转为字符串,但是绝对不要手动使用,完全等效于隐式转换,还不如+""

转数字:3种方法

1.parseInt(str/num); - parse解析 Int整型 - 专门用于将【字符串转为整数】 2.parseFloat(str); - parse解析 Float浮点型 - 专门用于将【字符串转为小数】

转布尔

Boolean(x);//万能的,任何人都可以转为布尔,但是绝对不要手动使用,完全等效于隐式转换,还不如 !!x 只有6个为false:0,"",undefined,NaN,null,false,其余全部都是true。 我们绝对不会手动使用,但是再分支或循环的条件之中,不管以后代老师写什么,他都会悄悄的转为一个布尔值,自带此方法 不管写什么,你只需要判断为不为这六个,不为这六个就是true,为这六个就是false

三目运算:简化分支的
```hp = user == 1 ? 15 : user == 2 ? 10 : user == 3 ? 5 : 1;


```js
    var i = 1;
    var r = parseInt(Math.random() * (100 - 1 + 1) + 1);
    var hp;
    var user = prompt('请选择难度:\n1.简单\n2.普通\n3.困难')
    hp = user == 1 ? 15 : user == 2 ? 10 : user == 3 ? 5 : 1;
    while (i <= 100) {
        if (hp > 0) {
            var user = parseInt(prompt('请输入一个数字,当前生命值为:' + hp));
            if (!isNaN(user)) {

                if (user > r) {
                    alert('您输入的数据大了')
                    hp--;
                } else if (user < r) {
                    alert('你输入的数据小了')
                    hp--;
                } else {
                    alert('恭喜您答对了')
                    break;
                }
            } else {
                alert('你恶意输入');
                hp--;
            }
  } else {
            alert('抱歉你没有答对,正确答案为:' + r);
            break;
        }
    }

day4

自定义函数Function

1.【声明方式】创建函数 function 函数名(形参列表){操作;return 返回值/结果;} 2.【直接量方式】创建函数 var 函数名=function(形参列表){ 操作; return 返回值/结果;} var 接住返回的结果=函数名(实参列表); 注意: //其实return的本意是退出函数,但是如果return后面跟着一个数据 //顺便将数据返回到函数作用域的外部,但是return只负责返回,不负责保存,所以调用函数时要自己拿个变量来接住他 //就算省略return,默认也有,会return一个undefined //*具体需不需要得到函数的结果,看你自己:如果有一天你在全局希望拿着函数的结果去做别的操作,那么记得加return //前辈们提供给你的方法,大部分基本上都加了return

作用域

1.全局作用域 2.函数作用域:局部变量 和 局部函数,在【当前函数调用时,内部可用】 带来了变量的使用规则:优先使用局部的,局部没有找全局要,全局也没有那就会报错 特殊点:缺点: 1、千万不要再函数中对着未声明的变量直接赋值 - 全局污染:全局本身没有这个东西,但是被函数作用域给添加上了 2、局部可以使用全局的,但是全局不能使用局部的 - 解决:看上面return

声明提前: - 只会出现在鄙视之中

规则:在程序正式执行之前,将var声明的变量(轻)和function声明的函数(重),都会悄悄的集中定义在当前作用域的顶部,但是赋值留在原地 强调: 声明方式创建的函数会完整的提前(第一种) 直接量方式创建的函数不会完整提前,只有变量名部分会提前(第二种) 何时使用:永远不会自己使用,干扰我们判断的 - 只会在笔试中遇到,为什么平时开发不会遇到呢? 只要你遵守以下规则:1、变量名和函数名尽量不要重复 2、先创建后使用

  var fn;
    var fn;
    function fn() {
        console.log(2);
    }
    function fn() {
        console.log(3);
    }

    fn = function () {
        console.log(1);
    }
    fn();//?  1

    fn();//? 1
    fn = 100;

    fn();//? u
    
    
    var fn;
    var fn;
    function fn() {
        console.log(1);
    }
    function fn() {
        console.log(3);
    }

    fn();//  3
    fn = function () {
        console.log(2);
    }

    fn = function () {
        console.log(4);
    }
    fn();// 4


    var a;
    function f1() {
        console.log(a);//? u
        a = 20;
        console.log(a);//? 20
    }
    console.log(a);//?  u
    a = 10;
    f1();
    console.log(a);//?  20
    a = 100;
    console.log(a);//?  100


    var a;
    function f1(a) {

        console.log(a);//?   u
        a = 20;
        console.log(a);//?  20
    }
    console.log(a);//?  u
    var a = 10;
    f1();
    console.log(a);//?  10
    a = 100;
    console.log(a);//?  100
    
    
    function f1() {
		console.log(a);//?1
		a = 20;
		console.log(a);//? 2
	}
	console.log(a);//?  u
	var a = 10;
	f1();
	console.log(a);//? 2
	a = 100;
	console.log(a);//?100

重载:相同的函数名,根据传入的实参的不同,自动选择对应的函数去执行,但是JS不支持,函数名如果重复了,后面的肯定会覆盖掉前面的

解决:在【函数内部】自带一个arguments的对象(类似数组对象):不需要我们去创建 - 哪怕没有写任何形参,他也可以接受住所有实参,所以默认你看他length长度为0

固定套路:

1、通过下标去获取传入的某一个实参:arguments[i] - i从0开始 2、通过length去获取到底传入了几个实参:arguments.length 通过判断传入的实参的不同,在内部去写判断,从而变相的实现重载

function calc() { console.log(arguments); if (arguments.length == 1) { return '求这两个的平方' + arguments[0] * arguments[0]; } else if (arguments.length == 2) { return '求这两个数字的和' + (arguments[0] + arguments[1]); } } console.log(calc(8)); console.log(calc(8, 8));

数组

***每个元素都有一个自己的位置,称之为叫做下标,下标都是从0开始的,到最大长度-1结束 1、创建数组:2种 1、*直接量方式:var arr=[];//空数组 var arr=[数据1,...]; 2、构造函数方式:var arr=new Array();//空数组 var arr=new Array(数据1,...); 3.获取数组之中的元素 数组名[i] 4.后续添加/替换元素: 数组名[i]=新数据; 如果下标处没人则为添加,如果下标处有人则为替换

数组具有三大不限制

1、不限制元素的类型 2、不限制元素的长度 3、不限制下标越界 - 不是一个好东西

注意:

1.如果获取元素时,下标越界,返回的是一个undefined 2.如果添加元素时,下标越界,会得到一个稀疏数组,如果我们搭配上我们学过循环去遍历获取每个元素,那么你会得到很多很多undefined

问题:自己数下标,难免会数错,导致我们下标越界

数组中有一个唯一的属性:length 语法:数组名.length 作用:获取到数组的长度,长度是从1开始的

三个固定套路:

1、向末尾添加元素:arr[arr.length]=新数据; 2、获取数组的倒数第n个元素:arr[arr.length-n]; 3、缩容:删除倒数n个元素:arr.length-=n;

遍历数组:固定公式: for(var i=0;i<arr.length;i++){arr[i];//当前次元素};

day5

1.*DOM:Document Object Model:文档对象模型:专门用于操作HTML文档的,提供了一些方法给你

DOM树概念

DOM将我们的HTML看作了是一个倒挂的树状结构,但是树根不是html标签,而是document的对象 document对象:不需要我们程序员创建,由浏览器的js解释器自动创建,一个页面只有一个document树根 作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法) DOM会将页面上的每个元素、属性、文本、注释等等都会被视为一个DOM元素/节点/对象

3、查找元素:两大方面:

1.直接通过HTML的特点去查找元素

1、通过 ID 查找元素:

var elem=document.getElementById("id值"); 特殊: 1、返回值,找到了返回当前找到DOM元素,没找到返回的一个null 2、如果出现多个相同id,只会找到第一个 3、记住控制台输出的样子,这个样子才叫做一个DOM元素/节点/对象,才可以下午去做操作 4、忘记此方法,不允许使用,id不好用,一次只能找一个元素。id留给后端用 5、其实根本不用查找,id直接可用

2、*通过 标签名 查找元素:
		var elems=document/已经找到的父元素.getElementsByTagName("标签名");
		特殊:
			1、返回值,找到了返回一个类数组DOM集合,没找到得到空集合
			2、js只能直接操作DOM元素,不能直接操作DOM集合,解决:要么下标拿到某一个,要么遍历拿到每一个。
			3、不一定非要从document开始查找,如果从document去找,会找到所有的元素,可以换成我们已经找到的某个父元素
3、*通过 class 查找元素:
		var elems=document/已经找到的父元素.getElementsByClassName("class名");
		特殊:
			1、返回值,找到了返回一个类数组DOM集合,没找到得到空集合
			2、js只能直接操作DOM元素,不能直接操作DOM集合,解决:要么下标拿到某一个,要么遍历拿到每一个。
			3、不一定非要从document开始查找,如果从document去找,会找到所有的元素,可以换成我们已经找到的某个父元素

2、*通过关系去获取元素:前提条件:必须先找到一个元素才可以使用关系

父元素:elem.parentNode; - 单个元素 子元素:elem.children; - 集合 第一个子元素:elem.firstElementChild; - 单个元素 最后一个子元素:elem.lastElementChild; - 单个元素 前一个兄弟:elem.previousElementSibling; - 单个元素 后一个兄弟:elem.nextElementSibling; - 单个元素

4、操作元素:前提:先找到元素,才能操作元素,3方面

1、内容:
	1、*elem.innerHTML - 获取和设置开始标签到结束标签之间的内容,支持识别标签的
		获取:elem.innerHTML;
		设置:elem.innerHTML="新内容";

	2、elem.innerText - 获取和设置开始标签到结束标签之间的纯文本,不识别标签的
		获取:elem.innerText;
		设置:elem.innerText="新内容";

	以上两个属性都是专门为双标签准备,而有一个单标签也是可以写内容,叫做<input />,我们如何获取?
	3、input.value - 专门获取/设置input里的内容
		获取:input.value;
		设置:input.value="新内容";

2、属性:
	获取属性值:elem.getAttribute("属性名");
	设置属性值:elem.setAttribute("属性名","属性值");

	简化版:
		获取属性值:elem.属性名;
		设置属性值:elem.属性名="属性值";
		简化版的缺点:
			1、class必须写为className - ES6(2015年)class变成了一个关键字
			2、不能操作自定义属性

3、样式:
	使用样式的方式:3种
		1、*内联样式
		2、内部样式表
		3、外部样式表 - 一阶段做开发用的都是外部样式表
	
	二阶段我们就要用js来操作【内联样式】
		1、不会牵一发动全身
		2、优先级最高

	获取样式:elem.style.css属性名;
	设置样式:elem.style.css属性名="css属性值";
	特殊点:
		1、css属性名,有横线的地方,去掉横线,变为小驼峰命名法
			border-radius     -----  borderRadius
		2、小缺陷:获取时,我们只能获取到内联样式,因为我们目前学的就是内联样式的操作

4、绑定事件:
	elem.on事件名=function(){
		操作;
		*****关键字this - 这个
			如果单个元素绑定事件,this->这个元素
			如果多个元素绑定事件,this->当前触发事件元素


一切的获取,往往都是为了判断
一切的设置,可以说是添加也可以说是修改
		

选项卡的题思路: 1.先建立4个li标签。4个div.(在一开始设置的时候,将div先关闭,给每个Li设置0,1,2,3的自定义下标) 2.遍历循环所有的li标签(集合) 3.用集合的名称【i】绑定点击事件 4.开启循环清楚所有的div和li上面的class(这里需要再次开启遍历循环) 5.给当前点击的li设置class为active 6.获取li上面提前准备好的自定义下标 7.给divs集合搭配上下表就能找到对应的。(注意className)写法。

	//找到了所有的li和div
			var lis=document.getElementsByTagName("li"),
			divs=document.getElementsByTagName("div");//[div,div,div,div]
			//循环所有的li
			for(var i=0;i<lis.length;i++){
				//每个li绑定了点击事件
				lis[i].onclick=function(){
					//开启循环清楚了所有的div和li上面的class
					for(var i=0;i<lis.length;i++){
						lis[i].className="";
						divs[i].className="";
					}
					//当前点击的li设置了class为active
					this.className="active";
					//获取了li上提前准备好的自定义下标!
					var i=this.getAttribute("dy");
					//给divs集合搭配上下标就能找到对应的
					divs[i].className="active";
				}
			}

表格的隔行变色。思路: 1.首先建立表格 2.找到所有的行 3.找到一个对应的计算器, 4.给按钮进行绑定事件(每次点击计数+1)j++; 5.判断奇数次还是偶数次 6.如果是奇数次,所有行都在变色,奇数行变粉色,偶数行变透明色 7.如果是偶数次,同理,所有行都在变色,奇数行、偶数行都在变

		//找到了第一个按钮
			var btn=document.getElementsByTagName("button")[0],
			//找到了所有行
			trs=document.getElementsByTagName("tr"),
			j=0;//当作一个计数器
			//给按钮绑定了点击事件
			btn.onclick=function(){
				//每次点击计数器+1
				j++;
				//判断奇数次还是偶数次
				if(j%2==1){//奇数次
					//所有行都在变色,奇数行变粉色,偶数行变透明色
					for(var i=0;i<trs.length;i++){
						if(i%2==1){
							trs[i].style.background="pink";
						}else{
							trs[i].style.background="transparent";
						}
					}
				}else{//偶数次
					//所有行都在变色,偶数行变天蓝色,奇数行变透明色
					for(var i=0;i<trs.length;i++){
						if(i%2==0){
							trs[i].style.background="skyblue";
						}else{
							trs[i].style.background="transparent";
						}
					}
				}
			}

购物车的案例:思路:1.遍历得到每一个按钮,2.为其绑定点击事件3.判断当前点击的是加号还是减号,4.如果是加号:找到数量,5将数量用一个变量保存起来,然后再重新上树再将数量+1;6.找到单价,取出文字。7.单价*数量, 8.减法反之。9.求每一行的小计,找到tbody里面的每一行,10.遍历每一行,找到每一行最后一个的,再累加起来。

	//找到了所有的按钮
		var btns = document.getElementsByTagName("button");
		//遍历得到每一个按钮
		for (var i = 0; i < btns.length; i++) {
			//为其绑定点击事件
			btns[i].onclick = function () {
				//判断当前点击的是+还是-
				if (this.innerHTML == "+") {//+
					//+按钮的上一个兄弟:数量span
					var span = this.previousElementSibling;
					//取出文字转为数字再+1,保存起来
					var spanV = parseInt(span.innerHTML) + 1;
					//重新上dom树
					span.innerHTML = spanV;
					//+按钮的爸爸的上一个兄弟:单价的td,取出文字
					var price = this.parentNode.previousElementSibling.innerHTML;
					//单价的数字*数量的数字,为其设置到+按钮的爸爸的下一个兄弟身上:小计的td
					this.parentNode.nextElementSibling.innerHTML = price * spanV;
				} else {
					var span = this.nextElementSibling;
					var spanV = parseInt(span.innerHTML) - 1;
					if (spanV > 0) {
						span.innerHTML = spanV;

						var price = this.parentNode.previousElementSibling.innerHTML;

						this.parentNode.nextElementSibling.innerHTML = price * spanV;
					}
				}
				//找到了tbody
				var tbody = document.getElementsByTagName("tbody")[0];
				//通过tbody找到了下面的每一行
				var trs = tbody.children;
				//遍历得到每一行
				for (var i = 0, sum = 0; i < trs.length; i++) {
					//取出每一行的最后一个儿子的文字,累加起来
					sum += parseInt(trs[i].lastElementChild.innerHTML);
				}
				//上树
				total.innerHTML = sum;
			}
		}

		var tbody = document.getElementsByTagName("tbody")[0];
		var trs = tbody.children;
		for (var i = 0, sum = 0; i < trs.length; i++) {
			sum += parseInt(trs[i].lastElementChild.innerHTML);
		}
		total.innerHTML = sum;