前端js

99 阅读16分钟

第一天

javascript:简称js是运行在javascript解释器或者特定引擎中的解释型/弱类型//面向对象脚本语言

1.js特点:代码可以用任何的文本编辑器编写,vascode/hbidder/记事本...

2、解释型语言,无需编译

3、弱类型语言:不需要进行规定,你想放什么就放什么 - 爱自由变量的数据类型是由值来决定的

强类型语言:先要规定你的变量要保存什么数据类型,才能往里面放入什么东西,比如java - 更严格

变量的数据是由 数据类型 来决定的 你能放入的值是什么

4.面向对象语言:程序员看任何东西都是一个对象,有一句话叫万物皆对象 以后经常会见到一种语法

    xx.xx或者xx.xx()
    一切东西都有自己的属性和方法:
        对象名.属性名;
        对象名.方法名();

js的作用:

1.客户单的数据计算:    购物车
2.表单的数据验证:    (手机号/身份证/邮箱/密码)
3.提供了事件:   (点击/鼠标的移入移除/键盘)
4.网页中一切css做不了的特效都由js完成
5.和服务端进行交付:   ajax

1、使用方式:2个

	1、在HTML页面写上一个标签: - 临时测试/上课用
		<script>
			js代码
		</script>

2、创建一个xx.js文件,在里面书写js代码,最后在HTML页面引入

2、JS的调试语句:代码运行期间,如果碰到错误,会报错,但是后续代码就不会执行了,甚至如果只是逻辑错误不是语法错误,那并不会报错,我们需要一个方式去帮助我们找到错误何在
    *1、在控制台输出日志:console.log(想要输出的东西);//打桩输出,疯狂打桩
 2、在页面上进行输出:document.write(想要输出的东西); - 要不得,如果绑定上了事件,会                 将页面上所有的内容全都替换掉
3、弹出框显示:alert(想要输出的东西); - 会卡主整个页面,必须关闭后用户才能看到HTML和CSS

3、js的语法规范:是严格要求区分大小写的,不能乱写

	比如:
		console.log();//正确
		console.Log();//错误

4.*变量:

硬盘:保存文件数据(外部储存器)
CPU:中央处理器:计算 暗黑3
内存:是【临时保存】程序在运行过程中,所需要用到的数据 - 本质来说我们的一个变量也是一个内存
内存空间:保存数据的一个地方
内存地址:内存空间的一个门牌号:大概长这样:0x00003021000310321,所以一般来说可以再起一个别名(变量名)

变量:值是可以改变的

何时:只要你以后需要经常使用的数据,都要先保存在一个变量中,以后使用变量名相当于使用变量值
语法:var 变量名=值;
比如 var name="天空";
var age=16;
var hobby="女";
特殊:
1.=:赋值符号将=右边的数据放到=左边的变量名之中
var age=18;
2.如果只是声明/创建/定义了,没有赋值的话,默认值为undefined  (是一个垃圾,没有任何作用),记住一定要赋值
3.取变量名尽量见名思意
    不能以数字开头
4.变量名是一个关键字,里面只能放入字符串,哪怕放的不是字符串,也会悄悄变成一个字符串
5.如果创建多个变量中间的var可以省略,中间的冒号换为逗号隔开,最后一个还是冒号结束
6.面试题
    如果是一个未声明的变量直接使用----会报错
    如果是一个声明过,但是未赋值的变量---会undefined

常量:一旦初始化后(第一次赋值),值不允许被修改----以后不会用到 语法:conset 常量名=值;----和变量除了关键字不同没有别的不同了

7.算数运算符:+ - * / %

    前面四个和小时候一模一样
但是特殊:
    1.%:取余,俗称模,两个数相除但是不取商,而是取除不尽的余数
    5%2=1
    作用:
        1.判断奇偶性
            num%2:结果为0 说明是一个偶数,结果为一说明是一个奇数
        2、获取某个数字的最后n位
	1234%10;//4
	1234%100;//34
	1234%1000;//234
    2.自带隐式转化:悄悄的转化数据类型会发生变化,我们程序员看不见
        常理来说只有数字才会参与算数运算,但是其实字符串也是可以,一定要切记下面几句话
       默认运算符左右两边都会悄悄转换为一个数字,再运算
特殊:
    1、+运算,只要碰上一个字符串,则都会变为字符串,+运算也不再是+运算,变成了拼接操作
2、-/%运算:有字符串也可以转为数字,但是必须是纯数字组成的字符串才可以,只有包含一个非数字字符,结果则为NaN

NaN:Not a Number:不是一个数字,但是确实是数字类型 - 垃圾

NaN参与任何算术运算结果都为NaN

NaN参与任何比较运算结果都为false - 不在三界之中

以后不希望见到undefined和NaN

8.js中的数据类型:

1.原始/基本/值类型---51.String---字符串,取值有无数个,必须写成"或";
    2.number---数字,值有无数个,直接写个数字就行了
    3.Boolean--布尔,取值只有两个,true或者false,多半用于判断
    4.Undefined - 取值只有一个默认值为undefined,没有任何用处 - 祖师爷犯下的错误
    5.Null - 空,取值只有一个null,作用,释放变量、节约内存
    
2.引用/对象类型:11个,每个对象都有很多很多的属性和方法等待我们去学习

扩展:

1.弹出一个用户输入框:var user=prompt("请示文字","默认值");

2.分支结构:根据条件的不同,选择一部分代码执行

语法:
一个条件一件事,满足就做,不满足就不做
        if(条件){
            操作
        }
一个条件两件事,满足就做第一件,不满足就做第二件
        if(条件){
            操作
        }else{
            默认操作
        }
多个条件多件事:满足谁就做谁
        if(条件一){
            操作一
        }else if(条件二){
            操作二
        }else{
            默认操作
        }

注意:else if想写几句就写几句

最后的else可以不写,但是条件都不满足的话则什么都不会执行
分支结构只要满足一个就不可能再走另一条路

# 第二天

二、算数具有隐式转换:其实其他的运算符也有隐式转换

自动转换:悄悄的,我们程序员是看不见的
默认将左右两边转为数字在运算

特殊: +运算:如果碰到一个字符串,两边都会悄悄的转换为字符串,再拼接

    - / * %:就算是字符串也会转换为数字,但是必须是纯数字组成的字符串才行,只要包含非数字字符,责问NaN
    某的人转为数字的结果
    true -> 1
    false -> 0
    undefined -> NaN
    null -> 0
    "100" -> 100
    "10a0" -> NaN
    NaN:Not A Number:不是一个数字,但是确实是数字类型,理解是不是有效范围的数字(不在三界之中)
    缺点:1、NaN参与任何算术运算结果都为NaN
    2、NaN参与任何比较运算结果都为false
                    问题:我们没有办法使用普通的比较运算来判断x是不是NaN
    解决:个人更爱反用
        **!isNaN(x) - 判断x是不是一个有效数字,此方法也具有数字的隐式转换**
        **true -> 说明x是一个有效数字
        false -> 说明x是一个NaN**

作用:防止用户恶意输入,要求用户输入的必须是一个有效数字,想要更加严格的管控用户需要以后学习正则表达式才行

显性/强制转换:

隐式转换的结果可能不是我们想要的我们程序员可以手动调用某些方法,进行数据类型的转换后,在运算
1.转字符串
    语法:var Str=x.toString()---x不能是undefined或者null,因为undefined和null是不能操作的
    此方法不重要,因为页面上默认的都是字符串
    
2.转数字:3个方法
       1. *var num=parseint(str/num);parde--解析,int--整数
    原理:从左向右一次读取每个字符,碰到非字符串就会停止,而且不认识小数点,如果以来就是非字符出啊,结果则为NaN
                            
                                console.log(parseInt(35.5));//35
				console.log(parseInt("35.5"));//35
				console.log(parseInt("35hello5"));//35
				console.log(parseInt("35px"));//35
				console.log(parseInt("35px555abc"));//35
				console.log(parseInt("0.35"));//0
				console.log(parseInt(布尔、undefinednull));//NaN
                                
        2.var num=parseFloat(str)parde--解析,Float--浮点数/小数
        原理;几乎和parseint一致,认识第一个小数点
        
                                console.log(parseFloat("35.5"));//35.5
				console.log(parseFloat("35.5px"));//35.5
				console.log(parseFloat("35.5.5"));//35.5
				console.log(parseFloat(".55"));//0.55
				console.log(parseFloat("px.55"));//NaN
				console.log(parseFloat(true));//NaN
        3.Number(x);--x是万能的,任何人都可以转为数字
            //垃圾,因为此方法完全等效于隐式转换,还不如*1 /1 -0,其实这就是隐式转换的底层原理

总结:Number何时都不使用 只要页面上带有单位的数字,我没都可以用parsexxx来去掉单位来变成数字

*****基本的函数:学3次才能完整的学完 - 第一等公民地位 url(图片路径) - 完成了一个根据图像路径显示图片的功能 rotate(角度值) - 完成了一个根据角度值旋转的功能 ...

js里面的函数 - 完成了一个xxxxxxxxxxxx的功能

1、什么是函数:也称之为方法,需要【预定义】后,可以【反复使用】的【代码段】
    2.创建函数并且调用函数
        第一步
        创建:fuction 函数名(){
            若干代码段
        }
        
        第二步:
        调用:两种方式
        1.直接再js里面写 函数名();程序员写几次就会触发几次
        2.绑定再页面的元素上,让用户自己来触发。用户触发一次就会执行一次-----提升用户的体验感
        <elem onclick=“函数名()”></elem>

何时要使用函数?

1.打开页面不希望立即执行
2.希望用户或者程序员来触发
3.希望能够被反复执行
4.本身就是一段独立的功能体:暂时理解为我没的每一个作业就是一个独立的功能体
5.要尽量将每一个功能体封装成一个函数,函数是js的一等公民地位,而且函数中的变量会自动释放

4.带有参数的函数

1.创建带参数的函数
    形参:就是一个变量名,只不过这里的变量不需要var,并没有保存到真正的值,形式参数简称形参
    function 函数名(形参......){
            函数体
    }
2.调用带参数的函数
    实参:实际参数,这个变量名所保存的值;
    函数名(实参.....);

一个函数可以执行相似的操作

比如实现任意两个数相加

                        function add(a,b){
				console.log(a+b);
			}
			add(1,2);
			add(3,4);

**注意:带参数的函数调用时,传入的实参个数和顺序都要和形参一一对应;

总结:1.如果你的函数体是固定不变的,则不需要你使用带参数的函数, 2.如果你的函数体希望根据传入的实参的不同,做的事儿也略微不同,则需要带有参数**

3、***分支结构: 1、代码中流程控制语句:3种 1、顺序结构: 默认结构,代码从上向下一步一步执行的

	2、分支/选择结构:
		根据条件,选择一部分代码去执行

	3、循环结构:
		根据条件,判断你是否需要再一次重复执行某一些代码
                    

2.*比较运算符:> < >= <= == !=

	作用:比较判断/条件中出现
	结果:以上六个运算符,结果一定是一个布尔值
	其实比较运算符也具有隐式转换,但是我不给你说,大部分情况下依然会转为数字在比较大小

扩展:*逻辑运算符:&&(与、并且) ||(或) !非

	&&:只有全部条件都满足,最后结果才为true
	    只要有一个条件不满足,结果则为false

	||:只有全部条件都不满足,最后结果才为false
	    只要有一个条件满足,结果则为true

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

第三天

****循环结构 1、问题:程序员打印输出1000句hello world console.log("1hello world"); ... console.log("1000hello world");

2、什么是循环?
    ****循环:反复执行【相同或相似】的操作,几乎是一瞬间就完成了很多次
    循环三要素:
        1.循环条件:开始  结束  重复执行的次数
        2.循环体:循环操作   干什么事
        3.循环变量:创建,并且要让他不断的改变(自增/自减),往往向着不满足循环条件再变化
        

3.while循环

    语法:
         var 循环变量=几;
         while(循环条件){
             循环体
             循环变量变化
         }
    原理:首先判断循环条件,如果条件为true,则执行一次循环体中的语句,然后再一次判断循环条件,如果条件为true则再执行一次循环体中的语句
    ...
    知道循环条件为false,才退出循环
    
    强调:循环是一次一次执行的,只是速度很快,而且循环没结束之前,会卡住后续代码

死循环:停不下来的循环,多半用于【不确定循环次数】的时候

  whiletrue){
      循环体;
      }
循环流程控制语句:退出循环:break;---死循环多半要搭配上进行使用,可以出现再任何一个循环中
             

*4、for循环:和while能做的事是一样的,只不过语法比while更简单,看上去也更加舒服 语法: for(var 循环变量=几;循环条件;变量的变化){ 循环体 }

	特殊:
	  1、创建循环变量部分可以同时创建多个变量,用,分隔
	  2、死循环:for(;;){循环体}

总结:
  1、while循环:一般用于 循环次数不明确的情况,死循环
  2、for循环:一般用于 循环次数明确的情况 - 大部分情况,个人也更推荐:语法更简单

2、*****数组

问题:保存1000个同学的姓名; var name1="何蓬1"; ... var name1000="何蓬1000";

 创建的变量名越多,开发的内存空间越大,网站性能会有所影响 - 以上这种写法:变量名太多了

 希望一个变量可以保存多个数据 - 数组

 数组中的元素:都是按照线性顺序排列
	特点:除了第一个元素,每个元素都有一个唯一的前驱元素
	      除了最后一个元素,每个元素都有一个唯一的后继元素
	*数组中的每一个元素都有一个唯一的位置序号,称之为【下标】,用来表示数组中的元素的位置,从0开始,到最大长度-1结束

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

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

    好奇创建这个数组有啥用?
	只是在保存数据而已,这些数据以后肯定有用

 2、获取/访问数组中的元素
	数组名[下标]

 3、添加/修改数组中的元素
	数组名[下标]=新元素

	特殊:
	  1、下标处如果没有人,则为添加
	  2、下标处如果有人,则为修改
	  3、如果下标越界 - 会导致我们的数组变为一个稀疏数组,不是好东西,因为我们迟早会去用循环遍历数组得到里面所有的数据,但是稀疏数组一定会出现一些undefined

 4、数组具有3大不限制
	1、不限制长度 - 优点
	2、不限制类型 - 优点
	3、不限制下标越界:
		获取时:下标越界,返回结果是一个undefined
		添加时:下标越界,导致我们的数组变为一个稀疏数组

	其实你可以想象,数组是一个长度无限的公交车,没人坐的地方也有一个默认值为undefined

 5、数组唯一的一个属性:length长度
	语法:数组名.length;

	*有了这个属性,我们就可以实现数组的三个固定套路:
		1、希望向末尾添加元素:arr[arr.length]=新元素
		2、获取倒数第n个元素:arr[arr.length-n]
		3、缩容:删除数组的倒数n个:arr.length-=n;

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

第四天

2、DOM树:DOM将HTML看做了是一个倒挂的树状结构,但是树根不是你们所理解的html标签

  *树根:是一个document对象,document对象是不需要程序员来创建的,由浏览器的js解释器负责创建,一个页面只有一个document
  作用:提供了一些属性和方法,可以让我们程序员去操作整个DOM树(增删改查每一个元素)
  DOM节点/DOM元素/DOM对象其实都是同一个意思:一个标签、文本、属性、样式;

3、*查找元素:

1、通过HTML的特点去查找元素:3种方式
	1、通过ID找到元素:var elem=document.getElementById("id值");
	   在当前DOM树中,根据元素的id,获取具体的DOM节点
	   找到了:返回对应的元素
	   没找到:返回null
	   特殊:1、如果页面上有多个重复的id,只会返回第一个
		 2、此方法找到的是单个元素 - DOM节点是可以直接用于做操作的
		 3、此方法你不能使用 - 以后id留给后端使用,而且此方法一次也只能找到一个元素操作起来不方便

           *2、标签名查找:var elems=document/已经找到的某个父元素.getElementsByTagName("标签名");
	   在当前DOM树中,根据元素的标签名获取元素们
	   找到了:返回是一个DOM集合/DOM类数组对象
	   没找到:空集合
	   特殊:1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么加下标拿到某一个,要么遍历拿每一个
			DOM集合:类数组对象,类似数组:1、都可以使用下标  2、都可以使用length  3、都可以遍历 和数组的区别我们以后在慢慢学习
		 2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素

       *3、class名查找:var elems=document/已经找到的某个父元素.getElementsByClassName("class名");
	   在当前DOM树中,根据元素的标签名获取元素们
	   找到了:返回是一个DOM集合/DOM类数组对象
	   没找到:空集合
	   特殊:1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么加下标拿到某一个,要么遍历拿每一个
			DOM集合:类数组对象,类似数组:1、都可以使用下标  2、都可以使用length  3、都可以遍历 和数组的区别我们以后在慢慢学习
		 2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素

2、通过节点之间的关系进行查找元素:前提:必须先要找到一个人,才能使用关系:
	父:xx.parentNode; - 单个元素
	子:xx.children; - 集合
	第一个儿子:xx.firstElementChild; - 单个元素
	最后一个儿子:xx.lastElementChild; - 单个元素
	前一个兄弟:xx.previousElementSibling;  - 单个元素
	后一个兄弟:xx.nextElementSibling;  - 单个元素

只有单个元素可以做操作,集合不行

4、操作元素:<标签 属性名="属性值" style="样式">内容</标签>

   1、内容:3个
   *1、innerHTML:获取 或 设置某个元素的内容部分 - 可以识别标签的
   获取:elem.innerHTML; - 多半用于判断操作
   设置:elem.innerHTML="新内容"; - 修改内容

2、innerText:获取 或 设置某个元素的文本部分 - 不能识别标签的
   获取:elem.innerText; - 多半用于判断操作
   设置:elem.innerText="新文本"; - 修改内容

   以上两个属性:都是为双标签准备的

3、value属性:专门为单标签(input)操作内容准备的
   获取:input.value; - 多半用于判断操作
   设置:input.value="新内容"; - 修改内容

2、属性:什么是属性:HTML属性:id、class、title、alt、style、type、href...只要是放在HTML标签上的我们都称为属性

1、获取属性值:elem.getAttribute("属性名"); - 多半用于判断操作
2、设置属性值:elem.setAttribute("属性名","属性值"); - 修改

以上两个方法有点繁琐 - 但是无敌的
能够简化:
	1、获取:elem.属性名; - 多半用于判断操作
	2、设置:elem.属性名="属性值" - 修改

	缺陷:1、不能操作自定义属性,只能操作标准属性
	      2class在ES6升级的时候成为了一个关键字,所以不可以在用class,换为了className

3、样式:

1、css定义的方式:3种
	1、内联样式 - 二阶段
	2、内部样式表
	3、外部样式表 - 最适合写样式的时候使用此方法
		
2、JS操作内联样式的好处
	1、优先级最高,写的JS样式必定会生效
	2、一次只会操作一个元素,不会牵一发动全身

3、语法:
   获取:elem.style.css属性名 - 多半用于判断操作
   设置:elem.style.css属性名="css属性值"; - 修改

   特殊:1、css属性名,要把有横线的地方,换成小驼峰命名法
	 2、唯一的缺陷:获取的时候,代老湿现在只交了你操作内联样式,目前不能获取样式表中的样式

4、元素绑定事件: 单个元素:elem.onclick=function(){ //操作 }

多个元素:
	for(var i=0;i<elems.length;i++){
		elems[i].onclick=function(){
			//操作
		}
	}