JS第一周

135 阅读12分钟

day1

1.变量:var 变量名=值

2.常量 const 创建后,不允许修改

3.数据类型 2类: 原始类型/值类型:5个

  1. number 直接写不加任何东西
  2. string 字符串 +""或''
  3. boolean 布尔值 :只有true和false
  4. null 空 唯一作用是释放变量,节约空间,提升性
  5. underfined 无卵用 引用/对象类型:很多

4.运算符

1.算术运算符 + - * / %

 % 模/取余
 作用
 1.判断奇偶2.取数的后n位
 2.带有隐式转换
 3.+运算碰上字符串,两边会转为字符串,执行拼接操作
    

2.比较运算符

<   >   <=  >=  ==  !==  ===(全等)  !==
结果:布尔值
隐式转换 转为数字再比较
特殊:如两边都是字符串,则按位PK每个字符串的十六进制
NaN参与任何运算结果都是false   !isNaN 

3.赋值运算符 = += -= *= /= %=

 1.=:赋值,将等号右边的东西,保持到左边的变量名
 

4.逻辑运算符:综合比较,结果也是布尔值

 &&:与(并且)
    全部结果满足就为true,一个不满足就是false
 ||或者
    只有一个满足就是true,全部不满足才是false

5.自增自减运算符

  ++ --
   i++  --> i+=1 --->i=i+1
   前++ 返回的是加了以后的值
   后++ 返回的是加之前的值 

6.位运算

  左移 m<<n m左移了n位  m*2(n次方)
  右移 m>>n m右移了n位  m/2(n次方)
  

扩展:用户输入框:var 变量=prompt("提示文字");

day02

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

3种:
	1、if...else...如何使用:3种情况
		1、一个条件,一件事,满足就做,不满足就不做
			if(条件){
				操作;
			}

		2、一个条件,两件事,满足就做第一件,不满足就做第二件
			if(条件){
				操作;
			}else{
				默认操作;
			}

		3、多个条件,多件事,满足谁,就做谁
			if(条件1){
				操作1;
			}else if(条件2){
				操作2;
			}else{
				默认操作;
			}

注意:

1else...if这句话想写多少,由程序员自己决定
2else这句话可以省略不写,但是不推荐,如果不写,条件都不满足的情况,则什么事儿都不会发生
3、分支走了一条路,就不会再走别的路

2、switch...case 分支:

语法:
	switch(变量/表达式){
		case1:
                        操作1;
                        break;
		case2:
                        操作2;
                        break;
		default:
		    默认操作;
	}

特殊:1、问题:默认只要一个case满足后,会将后续所有的操作全部做完

解决:break;

建议:每一个case的操作后面都跟上一个break

不加break:

1、最后一个操作default可以省略break

2、如果中间多个条件,做的操作是一样的,可以省略掉中间部分

面试题:if vs switch的区别?

1、switch...case:

优点:执行效率较高,速度快(他比较时,case做的不是范围查找,而是等值比较)

缺点:必须要知道最后的结果是什么才可以使用

2、if...else...:

优点:可以做范围判断

缺点:执行效率较慢,速度慢(他做的是范围查找)

建议:代码开发完过后,要做代码优化,要尽量的少用if...else...,多用switch...case和三目运算

3、三目运算:简化分支的

语法:

条件?操1:默认操作;===if...else... 

条件1?操作1:条件2?操作2:默认操作	===if...else if..else

注意:

1、默认操作不能省略,省略了会报错

2、如果操作复杂,不能使用三目运算:操作只能有一句话,如果操作有多句话还是推荐使用switch或if

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

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

1、转字符串:2种方法

1、var str=x.toString();//x不能undefined和null,他们不是对象
2、var str=String(x);//万能的,任何人都可以转为字符串,但是不要手动使用,完全等效于隐式转换,还不如+""
	不重要:页面上一切数据js获取到后都是字符串类型

2、转数字:3种方法

1、*parseInt(str/num); - parse解析 Int整型 - 专门用于将【字符串转为整数】
执行原理:从左向右依次读取转换每个字符,碰到非数字字符就停止转换,如果一来就不认识则为NaN,不认识小数点。
	console.log(parseInt(35.5));//35
	console.log(parseInt("35.5"));//35
	console.log(parseInt("3hello5"));//3
	console.log(parseInt("hello35"));//NaN
	console.log(parseInt("35px"));//35
	console.log(parseInt(".35px"));//NaN
	console.log(parseInt(true));//NaN
	console.log(parseInt(false));//NaN
	console.log(parseInt(undefined));//NaN
            console.log(parseInt(null));//NaN

2、*parseFloat(str);  - parse解析 Float浮点型 - 专门用于将【字符串转为小数】
	执行原理:几乎和parseInt一致,认识第一个小数点
	console.log(parseFloat(35.5));//35.5
	console.log(parseFloat("35.5"));//35.5
	console.log(parseFloat("3hello5"));//3
	console.log(parseFloat("hello35"));//NaN
	console.log(parseFloat("35.5px"));//35.5
	console.log(parseFloat(".35px"));//0.35
	console.log(parseFloat("35.5.5"));//35.5

3Number(x);//万能的,任何人都可以转为数字,但是绝对不要手动使用,完全等效于隐式转换,还不如 -0 *1 /1

3、转布尔:

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

day03

循环结构:反复执行 相同 或 相似的操作

循环三要素:
   1、循环条件:开始 - 结束,循环的次数
   2、循环体:做的操作是什么
   3、循环变量:记录着我们当前在哪一次,而且他会不断的变化

1、while循环:

    语法:
var 循环变量=几;
while(循环条件){
		循环体;
		循环变量变化;
		}
                    

执行原理:首先创建出循环变量,判断循环条件,如果条件满足,则做一次循环体操作,并不会退出循环,而会回过头再次判断循环条件满不满足,如果满足,则做一次循环体操作,...直到条件不满足,才会退出循环

特殊: 1、有的时候可能真的需要使用死循环:默认永远不会停下来的循环

		何时使用:不确定循环次数的时候
		while(true){死循环}
                    

2、死循环停下

	break; - 退出整个循环,多半都是用来搭配死循环的
	continue; - 退出本次循环,下一次依然会执行

2、for循环:和while的原理一样,但for比while更简洁

	语法:
		for(var 循环变量=几;循环条件;循环变量变化){
			循环体;
		}

	特殊:
		死循环:for(;;){}

面试题:while 和 for的区别? while和for在原理上几乎没有区别?

一般来说不确定循环次数的时候,会使用while循环 - 死循环
一般来说确定循环次数的时候,会使用for循环

3、do...while循环:废物:while我们都不想用,何况是更麻烦的do...while - 今日一见,不会再见

            语法:
		var 循环变量=几;
		do{
			循环体;
			循环变量的变化
		}while(循环条件)

面试题:

whiledo...while的区别?
区别只看第一次,如果第一次条件都满足,那么两者没有任何区别。
但是如果第一次条件不满足,while一次都不会执行
do...while至少会执行一次

2、Function的基础:

1、概念:Function 也叫函数也叫方法,【先预定义】好,以后可以【反复使用】的【代码段】

2、使用函数:
	1、定义/创建/声明:
		function 函数名(){
			函数体/代码段;
		}
		注:函数创建后,不会立刻执行,需要去调用函数

	2、调用函数:2种
		1、在js内部写:函数名(); - 程序员写几次就会调用几次

		2、在HTML上面绑定事件:
                        <elem onclick="函数名()"></elem> - 什么元素都可以绑定事件

	3、何时使用函数
		1、不希望打开页面立刻执行
		2、希望用户来触发提升用户的体验感
		3、每一个独立的功能(作业)都要封装为一个函数
		函数在js里的地位极高,函数是js的第一等公民
			
	4、创建出带有形参的函数 - 形参:其实就是一个变量,不需要加var,而且不需要赋值,所以叫做形式参数 - 简称形参
		function 函数名(形参,...){
			函数体/代码段;
			}

	5、使用带有形参的函数时,必须传入实参 - 实际参数,
				函数名(实参,...)

	注意:传参的时候顺序是不能乱的,必须和形参的顺序一一对应,数量不多不少

总结:
	1、不带参数的函数:用于执行一些固定操作
	2、带参数的函数:可以根据我们传入的实参的不同,做的略微不同

总结: 循环也能反复执行,函数也能反复执行 1、循环:几乎是一瞬间就完毕了 2、函数:需要调用后才会执行

day04

1、自定义函数Function

使用:
	1.创建:21、【声明方式】创建函数
			function 函数名(形参列表){
				操作;
				return 返回值/结果;
			}

		2、【直接量方式】创建函数:- 不推荐
			var 函数名=function(形参列表){
				操作;
				return 返回值/结果;
			}

			

	2.调用:
		var 接住返回的结果=函数名(实参列表);

                    return的本意是退出函数,
                    return只负责返回,不负责保存,所以调用函数时要自己拿个变量来接住他
		就算省略return,默认也有,会return一个undefined
		
		前辈们提供的方法,大部分基本上都加了return

	3、作用域:21、全局作用域:全局变量 和 全局函数,在页面的任何一个位置都可以使用。

		2、函数作用域:局部变量 和 局部函数,在【当前函数调用时,内部可用】

		优先使用局部的,局部没有找全局要,全局也没有那就会报错
			特殊点:缺点:
				1、不要在函数中对着未声明的变量直接赋值 - 全局污染
				2、局部可以使用全局的,但是全局不能使用局部的 - 解决:return

	4、声明提前: - 只会出现在笔试之中
		规则:在程序正式执行之前,将var声明的变量(轻)和function声明的函数(重),都会悄悄的集中定义在当前作用域的顶部,但是赋值留在原地
		
		强调:
			声明方式创建的函数会完整的提前(第一种)
			直接量方式创建的函数不会完整提前,只有变量名部分会提前(第二种)

		何时使用:永远不会自己使用,只会在笔试中遇到,
			遵守以下规则:
				1、变量名和函数名尽量不要重复
				2、先创建后使用

	5、重载:相同的函数名,根据传入的实参的不同,自动选择对应的函数去执行,但是JS不支持,函数名如果重复了,后面的会覆盖掉前面的
	目的:减轻压力,记住一个方法就可以执行很多的操作
		解决:在【函数内部】自带一个arguments的对象(类似数组对象):不需要去创建 - 哪怕没有写任何形参,也可以接受住所有实参,所以默认length长度为0
	固定套路:
	   1、通过下标去获取传入的某一个实参:arguments[i] - i从0开始
	   2、通过length去获取到底传入了几个实参:arguments.length
	   通过判断传入的实参的不同,在内部去写判断,从而变相的实现重载

1、数组:2种

1。创建数组
        1、直接量方式:var arr=[];//空数组
	var arr=[数据1,...];

        2、构造函数方式:var arr=new Array();//空数组
	var arr=new Array(数据1,...);

2、获取数组之中的元素:
		数组名[i]

3、后续添加/替换元素:
		数组名[i]=新数据;
		

4、数组具有三大不限制
	1、不限制元素的类型
	2、不限制元素的长度
	3、不限制下标越界 - 不是一个好东西
		如果获取元素时,下标越界,返回的是一个undefined
		如果添加元素时,下标越界,会得到一个稀疏数组,

	问题:数下标,数错,导致下标越界
	5、解决:数组中有一个唯一的属性:length
		语法:数组名.length
		作用:获取到数组的长度,长度是从1开始的

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

	6、遍历数组:不会拿出某个元素来使用,而是拿出每个元素来进行相同 或相似的操作 - 搭配上循环
	固定公式:
	for(var i=0;i<arr.length;i++){
		arr[i];//当前次元素
			}

day05

1、DOM:Document Object Model:文档对象模型:专门用于操作HTML文档的

2、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,只会找到第一个

			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、外部样式表 - 一阶段做开发用的都是外部样式表
	
	
	获取样式:elem.style.css属性名;
	设置样式:elem.style.css属性名="css属性值";
	特殊点:
		1、css属性名,有横线的地方,去掉横线,变为小驼峰命名法
			border-radius     -----  borderRadius
		2、小缺陷:获取时,只能获取到内联样式

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

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