JavaScript第一周学习

203 阅读14分钟
第一天:

1、javascript概述: 什么是:简称js,是运行在【js解释器】的【解释型】【弱类型】【面向对象】脚本语言

1、js解释器:不需要安装: 1、浏览器自带 2、后续在node.js服务器端 - 安装一个独立的js解释器

2、解释型:运行之前需要不需要检查语法是否正确,直接运行,碰到错误就停止运行,比如:javascript、php... - 宽松 编译型:运行之前需要检查语法是否正确,如果不正确,直接不能运行,比如:java、c、c#... - 严格

3、js特点: 1、代码可用任何编辑器编写 2、解释型 - 不需要检查对错,直接运行,碰到就停止 3、弱类型语言:是 由数据 决定了 数据的类型是什么 - 更自由 1 - number数字 "1" - string字符串 变量想保存什么数据类型都可以 - 随意

   强类型语言:是 数据类型 决定了 你要保存的数据是什么 - java	- 更严格
4、面向对象语言 - 万物皆对象(属性和方法)
	以后语法中:对象名.属性名;
		    对象名.方法名();

4、js的用途: 1、css能做的,js能做,css不能做的,js也能操作 2、ajax和服务器端进行交互 - 也是js的一部分

5、如何使用javascript:2种方式 1、在HTML页面上写上一个script标签,再在里面编写你的js代码 - 上课使用为了方便

2、在外部创建一个.js文件,在里面编写属于你的js代码 - 正式开发中使用
	<script src="js路径" type="text/javascript" charset="utf-8">
		不能再次编写代码了,必须将js代码放到js文件中
	</script>

建议:js都写在html的最后,好处2个:
	1、如果js非常的耗时,用户至少能看到html和css的效果
	2、后续我们js会操作html结构,如果js放在head中可能找不到运算

6、js代码: 1、注释:作用:1、提示自己/别人 2、玩 - 养成一个写注释的好习惯 单行注释:// 多行注释:/**/

2、输出方式 - 3种
	作用:打桩输出 - 检查错误

       *1、在F12的控制台输出日志:console.log(数字/"字符串"/变量); - 这才最重要的(都不会影响到用户的体验)
	2、在页面上输出,支持标签:document.write(数字/"字符串"/变量); - 缺点:如果绑定了一个按钮的事件,替换掉页面上所有的已有元素
	3、在弹出框输出:alert(数字/"字符串"/变量); - 缺点:卡主页面,必须关闭掉弹出框,用户才能看到页面的东西

3、*变量:
   硬盘:存储文件、数据 - 外部存储器
   CPU:中央处理器计算
   内存:是【临时存储】程序在运行过程中,所需要用到的数据
	内存空间:保存数据的一个地方
	内存地址:内存空间门牌号,0x0132asd123rtsa325sa,内存地址过长,为他取一个别名,就称之为变量名
   变量就是一个内存
	语法:var 变量名=值;
	作用:1、经常使用的数据,可以先提前保存起来
	      2、数据是可能被修改的

       *特殊:1、变量名不是随意的:1、不能以数字开头  2、不能使用关键字  3、尽量的见名知意
		 千万不要:
			var aa;
			var ab;
			var ac;
		 千万不要:
			var xingming; - 逼格低
		 尽量要:
			var name;
			var age;
			var gender;
		 变量名有一个很特殊name - 不管你保存的数据是什么,最后都会变成一个字符串

	     2、其实你想要创建一个变量只需要:var 变量名;其实就已经创建好了 - 不赋值也没关系,至少创建了不会报错了
		但是一般来说我们都要立马跟上赋值操作,因为默认值undefined是无用

	     3、如果创建了多个变量,可以省略掉中间var,分号都要换为逗号简写
		
	     4、其实var关键都可以不写,但是不推荐 - 导致全局污染

	     5、=:赋值符号,把=右边的数据保存在=左边的变量名之中,左边就单单纯纯的是一个变量名而已,不会变成变量的值

	     6、以后不管代老师说创建/声明/定义 - 同一个意思

		没有 = null
	
4、常量:一旦创建值不可以被修改
   语法:const 常量名=值;

   小练习:让用户输入半径,计算该圆的面积和周长
	公式:面积:pi*r*r	周长:2*pi*r

	

5、****数据类型:不同的数据类型的,做的操作也是不一样的
	1、原始/基本/值类型:5Number - 数字,取值:无数个
		String - 字符串,取值:无数个
		Boolean - 布尔值,取值:2个,表示一个【判断的结果】,true(真) 、 false(假)
		Undefined - 取值只有一个:undefined - 变量的默认值,undefined没有任何作用
		Null - 空,取值1个:null,作用,你用完了的变量(内存),可以用null释放 - 释放内存节约

	2、引用/对象类型:11个对象(属性和方法)

6、*算术运算符:+ - * / %
   m%n:取余,俗称模,m/n不取商,而且除不尽的余数
	作用:
		1、*判断奇偶性
			num%2 == 1 奇数
			num%2 == 0 偶数

		2、获取一个数字的后n位
			1234%10   -> 4
			1234%100  -> 34
			1234%1000 -> 234

		3、判断一个数字永远不超过几
			num%5 -> 结果永远不会超过5

	***算术运算其实具有隐式数据类型转换,默认都会转为数字,运算
	特殊:+运算,如果碰到一个字符串,那么两边的数据都会悄悄转换字符串,然后+运算变为拼接操作
	      - * / %其实字符串也可以转为数字,必须是纯数字组成的字符串才行,只要包含一个非数字字符结果则为NaN

*扩展:
  1、用户输入框:var user=prompt("提示文字","默认值");
  2、查看数据类型:typeof(变量/值/表达式);
  3、页面上获取到的数据类型都是字符串,如果你就想转为数字:
	parseInt(str) -> 转为整数
	parseFloat(str) -> 转为浮点数
  4、分支:作用:判断
	 语法:1、一个条件一件事,满足就做,不满足就不做 但是后续代码还是会执行的
		  if(判断条件){
			操作;
		  }

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

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

页面上获取到的数据始终都是一个字符串 1、***数据类型的转换: javascript是弱类型语言,由数据决定了数据类型是什么

对于不同数据类型的运算时,数据类型会自动进行转换 number+number=number number+string=string

1、隐式转换:我们程序员看不见,悄悄执行的转换操作 *算术运算符:+ - * / % *具有隐式转换:默认两边都转为数字,再运算 *特殊:1、+运算,碰上一个字符串,两边都会悄悄的转为字符串,变为拼接操作 2、- * / % 要是纯数字的字符串也可以转为数字,但是包含了非数字字符则为NaN 3、xx转为数字的话,会转为什么结果 true->1 false->0 undefined->NaN null->0 "100"->100 "100px"->NaN 4、NaN:Not A Number:不是一个数字,但是确实是number类型(不是有效的数字) 全是缺点:1、NaN参与任何算术运算,结果仍为NaN 2、NaN参与任何比较/关系运算,结果都为false,甚至不认识自己 - 带来了一个问题:我们没有办法使用普通的关系/比较运算去判断x是不是NaN 解决:!isNaN(x); 判断是不是有效数字 作用:防止用户输入的必须是一个有效数字 结果:true->是有效数字 false->是NaN

2、显式/强制转换:隐式转换出来的结果不是我们想要的,程序员可以手动调用一些方法进行数据类型的转换 1、转字符串:xx.toString();//转为字符串,但是undefined和null不支持,undefined和null不能使用.操作 基本不会使用,页面上获取到的数据始终都是一个字符串

2、*转数字:
	1、*语法:parseInt(str/num)
	执行原理:从左向右依次读取每个字符,碰到非数字字符则停止,并且不认识小数点,如果一来就不认识则为NaN
		console.log(parseInt(35.45));//35
		console.log(parseInt("35.45"));//35
		console.log(parseInt("3hello5"));//3
		console.log(parseInt("35px"));//35
		console.log(parseInt("hello35"));//NaN
		console.log(parseInt(true));//NaN

	2、*语法:parseFloat(str);
	执行原理:几乎和parseInt一直,但是认识第一个小数点
		console.log(parseFloat("35.45"));//35.45
		console.log(parseFloat("35.45.45"));//35.45
		console.log(parseFloat("35.4abc5.45"));//35.4
		console.log(parseFloat("35.45px"));//35.45

	以上两个API作用:强制转为数字的同时并且去掉单位

	3、语法:Number(x);//万能的,任何人都可以转为数字,垃圾:其实就是隐式转换,还不如隐式转换简单:
		 还不如:*1 /1 -0

2、*****函数:Function基础:也称之为方法 url(图片路径):完成了一个根据图片路径显示图片的功能 rotate(90deg):完成了一个根据角度值顺时针旋转45度的功能

js的自定义函数:完成了一个......功能

1、什么是函数:函数(Function)是一段被【预定义好的】,可以【反复使用】的代码
	      是个独立的功能体,可以将【若干】的代码放在里面

	
2、语法:2部分
	1、创建函数/方法
		function 函数名(){
			//若干代码段
		}
	
	2、调用函数/方法
		函数名();//程序员写几次就调用几次

		小技巧:绑定在页面元素之上,用户来触发了
		<elem onclick="js语法"></elem>

3、什么东西适合放在函数之中?
	1、不希望打开页面立刻执行,等用户来触发
	2、不希望只执行一次,可以反复触发
	3、本身就是一个独立的功能体:你写的每一个作业都是一个独立的功能体
	4、建议:以后每一个作业都要封装为一个函数:函数在js中具有第一等公民的地位,函数中的变量都是会自动释放的

4、带有参数的函数:
	榨汁机 - function:功能:榨汁
	原材料 - 参数:放入一个苹果、梨子、香蕉...
	如何创建带参数的函数:
		function 函数名(形参,...){//形参(形式参数)其实就是一个变量,只不过不需要var
			函数体;
		}

	调用带参数的函数的时候:
		函数名(实参);//实际参数

		function zzj(fruit){
			console.log("榨"+fruit+"汁");
		}
		
		zzj("苹果");
		zzj("梨子");

	强调:
	  1、传入实参的顺序一定要和形参的顺序对应上
	  2、函数不一定非要有参数:1、如果你的操作是固定的,则不需要传递参数
			          2、根据传入的实参不同,做的操作略微不同,则需要添加参数

3、***分支结构: 1、程序的结构:3种 1、顺序结构:默认结构,从上向下依次执行每一句代码 2、分支结构:根据判断条件,选择一部分代码去执行(只会走一条路) 3、循环结构:根据判断条件,选择是否重复执行某一段代码

2、比较/关系运算符:> < >= <= == != 结果:以上六个运算符结果都为布尔值:true、false 往往比较运算符出现在分支、循环的判断条件之中 其实关系运算符也具有隐式转换:

3、if结构: 1、一个条件一件事,满足就做,不满足就不做 if(判断条件){ 操作 }

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

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

	强调:
	  1、最后的else是可以省略的,但如果条件都不满足,则分支白写
	  2、条件有时候写的顺序需要注意,因为分支只会走一条路

扩展:逻辑运算符: &&:与(并且) 只有全部条件都为true,最后结果才为true 只要有一个条件为false,最后结果就为false

||:或
    只有全部条件都为false,最后结果才为false
    只要有一个条件为true,最后结果就为true

 !:颠倒布尔值:
	!true -> false
	!false -> true      
            
            
            

###### 第三天:

1、****循环结构: 1、问题:在控制台打印输出10000句hello world console.log("1hello world") ... console.log("10000hello world")

2、什么是循环:【反复执行相同 或 相似的操作】 生活中: 1、吃饭 2、睡觉 3、学习 4、上班 5、活着

循环三要素:
	1、循环条件:开始、结束:重复执行的次数
	2、循环体:循环的操作:要干什么
	3、循环变量,并且 变量需要不断的变化

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

执行原理:先判断循环条件,如果条件为真,则执行【一次】循环体
	  然后再判断循环条件,如果条件为真,则执行再【一次】循环体
	  ...
	  直到条件为假,循环才会结束
注意:循环是一次一次执行的 - 并不是同事执行的,只不过计算机的CPU计算速度比较快

死循环:永远不会结束的循环 - 保存死循环也是可以退出循环
  何时:不确定要执行的具体次数,但往往死循环会搭配上break进行退出
	while(true){
		循环体
	}

循环退出语句:break; - 出现循环之中

4、*for循环:while能做,for也能做,而且for看上更加的简单/简洁 语法:for(var 循环变量=几;循环条件;变量的变化){ 循环体 }

     特殊:
   1、死循环:for(;;){循环体} - 两个分号一个不能少

   2、循环变量处其实可以创建多个变量

   3、也支持break

总结:
  1while:一般都不用,何时使用:不确定循环次数的时候
  2for:常用,确定循环次数时

2、*****数组: 1、问题:保存1000个人的姓名? - 如果是以下这种写法,我们开辟1000个内存空间 var name1="张三1" ... var name1000="张三1000"

解决:数组:多个数据/元素组成的一个集合,保存在一个变量中
	    数组中的元素都是按照线性顺序来排列,除了第一个元素,每个元素都有一个唯一的前驱元素
					       除了最后一个元素,每个元素都有一个唯一的后继元素
	    *数组中每个元素都有一个唯一的位置序号,称之为【下标】,用来表示数组中的每一个元素
			下标是从0开始,到最大长度-1

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

2、构造函数方式:此方法还有一个坑,但是我不说
	var arr=new Array();//空数组
	var arr=new Array(数据,数据,...);

3、*访问数组: 1、获取数据 数组名[下标];

	特殊:1、下标越界,获取到的是一个undefined

2、添加数据
	数组名[下标]=新数据;

	特殊:1、如果下标处已有元素,则为替换
	      2、如果下标越界,会导致你的数组变成一个稀疏数组,中间就会出现很多的undefined,而且下标也不再连续

    结论:数组具有3大不限制:
	1、不限制元素的长度
	2、不限制元素的类型
	3、不限制下标越界 - 但是这个操作并不是好事情,强烈不推荐下标越界

4、*数组对象 - 唯一属性 正是因为我们自己数下标容易数错,提供了一个属性:语法:数组名.length - 获取到数组的长度

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

5、*遍历数组:将数组中的每个元素都取出来 执行 相同 或 相似的操作 公式:for(var i=0;i<arr.length;i++){ arr[i];//当前次获取到的元素 }

###### 第四天:

去重的思路: 1、循环:拿到每个文字 2、循环:拿到刚刚那个字后面的每个文字 3、做比较 4、如果比较成功,循环:从重复的那个字开始,拿到后面的每个文字,把前一个赋值为后一个 5、删除最后的多出来的一个undefined,以及j--,因为没删除一个元素,后面的元素就会向前进一步


1、javascript由三部分组成 1、ECMAScript(ES3/5/6) - 核心语法:前三天学习的内容 - 内功心法(以后可能做任何操作都离不开他们) 2、DOM - Document Object Model:文档 对象 模型 - 操作文档(HTML) - 外功招式(特效) 3、BOM - Browser Object Model:浏览器 对象 模型 - 操作浏览器 - 有重点但是用处不大

2、DOM概念: DOM树:把HTML看做了是一个倒挂的树状结构,但是树根并不是你们理解的HTML,而是document对象(属性和方法) document对象不需要程序员创建,由浏览器的js解释器自动创建,一个页面只有一个document 有一些属性和方法等待我们去学习 注意:DOM会把页面上的所有的元素都看做是一个DOM对象、DOM节点、DOM元素 - 都是同一个意思

3、获取元素: 1、通过 HTML 的属性去获取元素 1、通过ID: 语法:var elem=document.getElementById("id值"); 返回:是一个DOM对象/DOM节点/DOM元素,才可以直接做操作 特殊: 1、如果id重复了,只会返回第一个 2、如果没找到,返回的是一个null 3、此方法白学,以后不准使用

2、*通过 标签名:
   语法:var elems=document/parent.getElementsByTagName("标签名");
   返回:是一个DOM集合 - 是一个类数组对象:类似数组,也可以使用下标、length、遍历
   特殊:
	1、一个DOM集合是不允许直接做操作的,除非加下标得到某一个 或 遍历得到所有人,才能做操作
   	2、如果没找到,返回的是一个空集合
	3、此方法不一定非要写document,也可以写一个parent(已经找到的某个父元素)
		如果是写的document,则会找到页面上所有的标签
		而写的是parent,只会找到parent下面的所有的标签

3、*通过 class名:
   语法:var elems=document/parent.getElementsByClassName("class名");
   返回:是一个DOM集合 - 是一个类数组对象:类似数组,也可以使用下标、length、遍历
   特殊:
	1、一个DOM集合是不允许直接做操作的,除非加下标得到某一个 或 遍历得到所有人,才能做操作
   	2、如果没找到,返回的是一个空集合
	3、此方法不一定非要写document,也可以写一个parent(已经找到的某个父元素)
		如果是写的document,则会找到页面上所有的标签
		而写的是parent,只会找到parent下面的所有的标签

2、*通过 节点之间的关系 获取元素 前提:至少先要找到一个元素,才能找关系

1、父元素:xx.parentNode - 单个元素
2、子元素:xx.children - 集合
3、第一个儿子:xx.firstElementChild - 单个元素
4、最后一个儿子:xx.lastElementChild - 单个元素
5、前一个兄弟:xx.previousElementSibling - 单个元素
6、后一个兄弟:xx.nextElementSibling - 单个元素

4、操作元素:<elem 属性名="属性值" style="样式">内容 1、内容: 1、*innerHTML:用于操作双标签,能够识别标签 获取:elem.innerHTML; 设置/修改:elem.innerHTML="新内容";

2、innerText:用于操作双标签,不能识别标签
   获取:elem.innerText;
   设置/修改:elem.innerText="新内容";

3、*value:用于操作input
   获取:elem.value;
   设置/修改:elem.value="新内容";

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

简化版:
  获取属性值:elem.属性名;
  设置属性值:elem.属性名="属性值";

  简化版注意:两个小缺点:
	1class必须写为className
	2、只能操作标准属性,不能操作自定义属性

建议:开发中优先使用简化版,简化版实现不了的时候在用复杂版代替

3、样式: 内联样式: 优点:1、优先级最高 - 保证js用户触发一定会生效 2、不会牵一发动全身 - 只会操作当前元素 缺点:1、获取样式时,一定要保证此样式在内联样式中

获取样式:elem.style.css属性名;
设置样式:elem.style.css属性名="css属性值";

特殊:css属性名的写法,如果有横线要去掉横线,变为小驼峰命名法
	原来CSS				JS:
	background-color		backgroundColor
	width				width
	border-top-width		borderTopWidth

4、*绑定事件: 为什么不用以前的绑定方式了呢? 保证HTML和CSS和JS分离

语法:elem.onclick=function(){
		点击后要执行什么代码
		***this关键字:
			单个元素绑定事件,this->这个元素
			多个元素绑定事件,this->当前触发事件的元素
      }

一切的获取的作用:往往都是用于判断 一切的设置的作用:说白了修改