JavaScript入门第一周复习

148 阅读12分钟

JavaScript

JavaScript概述

简称js,是一个运行在【js解释器】中的一个【解释型】【弱类型】【面向对象】脚本语言

1、js解释器

      1、浏览器自带js解释器
      2、以后也会安装一个js解释器 - Node.js
          

2、

       编译型:在运行程序之前,需要先检查程序是否有报错,如果有报错直接不运行,比如:java、c#、c++... - 严格
       解释型:在运行程序之前,不需要检查程序是否有报错,直接运行,碰到错误了才会停止,比如:JavaScript、php... - 自由
           

3、

       弱类型:变量想保存什么数据类型就保存什么数据类型,由数据决定了数据类型是什么,比如:javascript、php... - 自由
       强类型:变量能保存什么数据类型,需要提前声明出来,由数据类型来决定了能保存的数据是什么,比如:java... - 严格
           

JavaScript由三部分组成

       1、ECMAScript(3/5/6)- 核心语法               内功心法
       2、DOM - Document Object Model:文档对象模型, 外功招式 - 操作文档(html/css)
       3、BOM - Browser Object Model:浏览器对象模型,外功招式 - 操作浏览器(相对较少)- 兼容性问题

JavaScript特点

       1、用任何文本编辑器编写代码:HBuilder、VSCode、记事本开发都可以...
       2、解释型
       3、弱类型
       4、面向对象:以后我们会经常见到带有一种写法:万物皆对象
                   对象名.属性名;
                   对象名.方法名();

JavaScript如何使用

js的引入方式

        1、在HTML中书写一个script标签: - 仅用于临时测试
		<script>
			js代码
		</script>
        2、创建一个xx.js文件,再在HTML进行引入 - 正式开发中
		如何引入:<script src="xx.js">//不能在这里书写js代码了</script>
           建议js放在HTML和CSS的后面,最好是最后 

打桩输出

        疯狂打桩:非常重要的一种找错方式:3种
        *1、在控制台输出日志:console.log(想要输出的内容);
         2、在页面上输出:document.write(想要输出的内容); - 可以识别标签,缺点:如果有点击事件触发document.write会导致页面原来的HTML全被覆盖掉
         3、用警告框输出:alert(想要输出的内容); - 缺点:会卡主页面,只能看到白板

变量和常量

变量

         *变量:简单来说就是一个值可以发生变化的数据/量。
          何时:如果以后某一个数据我们要反复使用,最好都把他先保存成一个变量,以后只需要使用变量名相当于就是在使用变量的值;
          语法:var 变量名=值;
          特殊:
                1、面试题:内存和变量有区别吗?
                          硬盘:保存数据/文件,机械硬盘和固态硬盘 - 外存
		      CPU:中央处理器 - 用于计算的
		      内存:是程序在运行过程中【临时】用到的数据
		      内存空间:实际保存数据的地方
		      内存地址:内存空间的一个门牌号:0x000012edae21fsdhgi11,往往会取一个别名(变量名),以后使用这个变量相当于就在拿内存空间里面的数据
		
                2、变量名其实不是随便的
                     1、不能以数字开头
                     2、建议:尽量的要见名知意:
			以英文为主:比如var name="xx";
			var xingming="某某某"; //不推荐拼音,太low
			最不推荐:var aa; - 没有见名知意的效果
				 var ab;
				 var ac;
                     3、使用驼峰命名法更加推荐
                     4、name是一个关键字,不管你保存的数据类型是什么,都会悄悄的变成一个字符串
                     5、千万不要把关键字当做变量名

                 3、如果你想要创建多个变量,没有必要每个都写var,中间的变量都可以省略掉var关键字,中间用,(英文逗号)间隔,最后一个还是用;(英文分号)结束
                 

常量

          一旦创建后,值不允许被修改了
          何时:用途和变量几乎一致,几乎不用,现实中用的少的,代码中也用的少
	  生活中的常量:
		1、pi:3.14158926;
		2、一年一定是365/366天
		3、一天24个小时
		...
          语法:const 常量名=值;

算术运算符

            + - * / %     
            %:取余,俗称模,两个数相除,不取商,而取除不尽的余数
            作用:
		*判断某个数字的奇偶性:num%2	如果结果为0说明是偶数,如果结果为1说明是基数
		取出一个数字想要的后n位
                    
            特殊:
		1、算数运算符具有隐式转换,默认:都是转为数字在运算
		   特殊在+运算,如果碰到了一个字符串,两边都会悄悄的转为字符串,变成了一个拼接操作
		2、-*/%:其实字符串也能转为数字,但是前提是一个纯数字组成的字符串,但凡包含一个非
		   数字字符,则为NaN:纯粹的垃圾:Not a Number:直译,不是一个数字,但是确实是数字类型,但是不在三界之中
				全是缺点:
					1、NaN参与任何算数运算结果仍为NaN
					2、NaN参与任何比较运算结果都为false  

数据类型

            原始/基本/值类型:51String - 字符串,取值有无数个,但是必须写上""''
		2Number - 数字,取值有无数个,直接书写数字即可
		3Boolean - 布尔,取值只有2true(真,对)和false(假,错) - 多半用于表示判断的结果
		4Undefined - 变量如果声明了,但是没有赋值的话,默认值就为undefined,只有这一个取值 - 垃圾:没有任何用处
		5Null - 空,取值也只有一个null,释放内存/变量

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

数据类型转换

隐式转换

            悄悄地,程序员看不见的转换
            算术运算符具有隐式转换
            默认:都是转为数字,在运算
                        特殊:  1、不管是什么运算,只要没碰上字符串,都会悄悄的转为一个数字
                                        true->1
                                        false->0
                                        undefined->NaN
                                        null->0
                                2、+运算并且碰上字符串,则为拼接,最后的结果也就还是一个字符串
                                3、-*/%,就算是字符串也可以转为数字,前提是纯数字组成的字符串,但是如果包含了一个非数字字符,则为NaN                 

显式转换:也叫作强制转换

            何时使用:隐式转换出来的结果不是我们想要的,先强制转换为需要的数据,再运算
            
            转字符串:
                1、x.toString();//x不能是undefined和null - undefined和null不能.
                2String(x);//万能的,任何人都可以转为字符串,不重要
                    不重要的原因:
                        1、页面上一切的数据都是字符串
                        2String(); 完全相当于隐式转换 - 还不如+""

           *转数字:
                1、*parseInt/Float(str);//专门为字符串转数字准备的
                    原理:从左向右依次读取每个字符,碰到非数字字符就停止,如果一来就不认则为NaNInt不认识小数点,Float认识第一个小数点
                2Number(x);//万能的,任何人都可以转为数字,不重要 - 完全相当于隐式转换 - 还不如-0 *1 /1

             转布尔:
                   Boolean(x);//万能的,任何人都可以转为布尔,不会手动使用的,还不如:!!x
                   ***只有6个会为false0,"",undefined,null,NaN,false,其余都为true
                   在分支、循环的条件之中,他都会悄悄的隐式转换为布尔值,只需要考虑为true还是为false

函数

            Function:自定义函数:也称之为方法:需要【预定义好】的,可以【反复使用】的一个【代码段】
            js中的函数 - 完成了一个。。。的功能

            1、创建函数:
                    function 函数名(){
                            代码段;//若干操作
                    }

            2、调用函数:
                    1、直接在js中程序员写几次调用,就会执行几次操作:
                            函数名();

                    2、让用户来自己触发:
                            <elem onclick="函数名()"></elem>

            3、何时使用函数:
                    1、所有功能都要封装成一个函数,因为函数的js地位很高,属于第一等公民地位
                    2、不希望打开页面立刻执行
                    3、能够反复执行
                    4、他是个独立的功能体
                    5、你不是自己释放内存,函数调用完毕会自动释放内存/变量

            4、带参数的函数:
                    电饭煲 -> 看做是一个函数:功能:把....煮熟
                    原材料 -> 参数	

                    语法:形参:其实就是一个变量名,只不过不需要写var这个关键字,每个形参之间用,间隔,形式参数,简称形参
                            function 函数名(形参,...){
                                    函数体;
                            }

                    调用:实参:实际参数
                            函数名(实参,...);

                            function zwjs(name,age,hobby){
                                    console.log("我的名字叫"+name+",今年"+age+"岁,喜欢"+hobby);
                            }
                            zwjs("张三丰",128,"打太极");

                    特殊:实参的个数以及顺序 和 形参的个数以及顺序都要一一对应

            5、普通函数:操作永远是固定的
               带参数的函数:根据传入的实参,执行略微不同的操作

代码流程控制语句

	1、顺序结构:默认的,代码从上向下
	2、分支结构:根据条件不同,选择部分代码执行
	3、循环结构:根据条件满不满足,考虑要不要再执行一次相同 或 相似代码
            

比较运算符

< >= <= == != === !==

                  结果:布尔值
                  隐式转换:默认,转为数字,再比较大小
                  注意:==才叫比较		=叫赋值:右边的东西放到了左边保存起来
                  特殊:1、如果参与比较的左右两边都是字符串,则是按位PK每个字符的十六进制unicode号(十进制ascii码)
                  0-9<A-Z<a-z<汉字:常识:汉字的第一个字:一:unicode:4E00 - ascii:19968
                                             最后一个字:龥:unicode:9FA5 - ascii:40869

                        2、NaN参与任何比较运算结果都是false,所以没有办法用普通的比较运算判断是不是NaN
                                !isNaN(x);

                        3、undefined==null;//true
                           区分:undefined===null;
                           === !==:不带隐式转换的等值比较和不等比较,要求数值相同,并且数据类型也要相同
            

逻辑运算

                  &&:全部满足,才true	
                      一个不满足,则false

                  ||:全部不满足,才false
                      一个不满足,则true

                   !:颠倒布尔值

分支结构

            1、一个条件一件事,满足就做,不满足就不做
                        if(条件){
                                操作;
                        }

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

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

                else可以省略,但是不推荐
         

循环结构

            问题:在控制台打印输出1000句hello world
                console.log("1hello world");
                        ...
                console.log("1000hello world");

解决:循环结构:反复执行相同 或 相似的代码

            循环三要素:
                1、循环条件:从哪里开始,到哪里结束
                2、循环体:操作-要做什么事
                3、循环变量、变量还要变化

while循环

            循环从宏观上看是一起执行的,但是微观上看是一次一次执行的,只不过这个执行速度很快
            语法:
                var 循环变量 = 几;
                while(循环条件){
                        循环体;
                        循环变量变化;
                }

            执行原理:先判断循环条件满足吗,如果为true,则执行循环体一次,再一次判断循环条件满足吗,如果为true,则再执行循环体一次
                      .......直到循环条件不满足,才会退出循环

            特殊:
              死循环:永远不会结束的循环 :往往不确定循环次数的时候就要使用
                    while(true){
                            循环体;
                    }
              往往死循环还要搭配上,退出循环语句:break; - 只能写在循环里面

for循环

            执行原理跟while一模一样,只是语法更加的简洁
                for(循环变量的创建;循环条件;变量的变化){
                        循环体;
                }

            特殊:1、循环变量的创建和循环变量的变化,其实可以写多个

                  2、死循环:for(;;){操作}

            总结:1、while:语法更加繁琐,建议只用于不确定循环次数的时候 - 死循环
                  2、for:语法更加简洁,建议只用于确定循环次数的时候 - 大部分情况
	 
            问题:函数 和 循环 都是可以反复执行的,区别在哪里?
                函数 - 要么程序员调用几次,执行几次,或者,用户来触发几次,执行几次
                循环 - 程序员写好的,而且几乎是一瞬间就执行完毕了的
            

数组

            一个内存空间,可以保存多个数据
            
            数组里面的元素,是按照线性顺序排列的,除了第一个元素,每个元素都有一个唯一的前驱元素
            除了最后一个元素,每个元素都有一个唯一的后继元素
           *每个元素都有一个唯一的位置序号,称之为【下标】:从0开始,到最大长度-1
            
            1、创建数组:2种
                    1、*直接量方式:var arr=[];//空数组
                               var arr=[元素,...];

                    2、构造函数方式:var arr=new Array();//空数组 - 不推荐,直接量方式是ES2过后才添加上的,原来只有构造函数方式
                                    var arr=new Array(元素,...);

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

            3、添加/覆盖:
                数组名[下标]=新元素;
                特殊:
                  1、下标处没有元素,则为添加
                  2、下标处有元素,则为覆盖/替换

            4、数组的三大不限制:
                1、不限制元素的类型
                2、不限制元素的个数
                3、不限制下标越界 - 算是一个缺点:
                        获取时 - 下标越界,返回undefined
                        添加时 - 下标越界,会变成稀疏数组,导致下标不连续,不好

            5、数组有一个唯一的属性:数组名.length; - 获取到数组的长度
                ***三个固定套路:
                        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];//当前次元素
                        }
            

DOM

概述:Document Object Model:文档对象模型,外功招式 - 操作文档(html/css)

DOM树:DOM将HTML看做了是一个倒挂的树状结构:树根其实是一个叫做:document的对象 document对象:不需要我们创建,一个页面自带一个document对象,由浏览器的js解释器自动创建 *作用:只要是对象一定有两个东西(属性和方法):提供了我们找到元素&操作元素的方法

查找元素

通过 HTML 特性去查找元素

            1、通过ID查找元素:
                    var elem=document.getElementById("id值");//get得到 element元素 by通过
               特殊:
                  1、如果有多个相同的id,只会找到返回第一个 - id是唯一不重复的
                  2、*返回的结果:<标签 id="ID名">xxx</标签> - 这个才能称之为叫做一个DOM元素/节点/对象,才可以用于后续的操作
                  3、我们把id留给后端使用,而且id也不好用,一次只能找到一个元素

            2、通过标签名查找元素:
                    var elems=document/parent.getElementsByTagName("标签名");
                特殊:
                   1、返回的结果:不是一个DOM元素/节点/对象,是一个DOM集合,是不能直接用于做任何操作的
                           解决:要么用下标拿到某一个,要么用遍历拿到每一个
                   2、parent:代表的是你已经找到的某个父元素

            3、通过class名查找元素:
                    var elems=document/parent.getElementsByClassName("class名");
                特殊:
                   1、返回的结果:不是一个DOM元素/节点/对象,是一个DOM集合,是不能直接用于做任何操作的
                           解决:要么用下标拿到某一个,要么用遍历拿到每一个
                   2、parent:代表的是你已经找到的某个父元素
            

通过 关系 获取元素

前提:至少要先找到一个元素

            父元素:elem.parentNode; - 单个元素
            子元素:elem.children; - 集合:集合不能直接做操作
            第一个儿子:elem.firstElementChild; 
            最后一个儿子:elem.lastElementChild;
            前一个兄弟:elem.previousElementSibling;
            后一个兄弟:elem.nextElementSibling;

操作元素

<标签 class id title href style="样式"> 内容 </标签>

内容

            1、innerHTML:获取 或 设置元素的内容部分,并且能够识别标签
                获取:elem.innerHTML;
                设置:elem.innerHTML="新内容";

            2、innerText:获取 或 设置元素的文本部分,不能识别标签
                获取:elem.innerText;
                设置:elem.innerText="新文本";

               以上两个操作都是针对双标签使用

            3、value:获取 或 设置input的内容部分
                获取:input.value;
                设置:input.value="新文本";

属性

            1、获取属性值:elem.getAttribute("属性名");
                   简化版:elem.属性名;

            2、设置属性值:elem.setAttribute("属性名","属性值");
                   简化版:elem.属性名="新属性值";

            简化版虽然简单,但有缺陷:
                   1class必须写为className
                   2、只能操作标准属性,不能操作自定义属性

            优先使用简化版,简化版满足不了,再用复杂版做补充

样式

            	1、内联
                2、内部
                3、外部 - 符合内容HTML与样式CSS与行为JS的分离原理

                更喜欢操作内联样式:
                        1、内联的优先级最高 - 保证我们js写的样式必然生效
                        2、只会操作当前元素 - 不会牵一发而动全身

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

                     特殊:1、设置css属性名如果有横线要去掉横线,变为小驼峰命名法
                           2、获取只能获取到内联样式

获取:往往用于判断

设置:其实就是修改

绑定事件

            符合内容HTML与样式CSS与行为JS的分离原理

            单个元素:
                    elem.onclick=function(){
                            this->就是绑定事件的这个元素
                    }

            多个元素:
                    for(var i=0;i<elems.length;i++){
                            elems[i].onclick=function(){
                                    this->是当前触发事件的元素
                            }
                    }
            this关键字:目前只能在【事件】中使用
                      单个元素绑定事件this->这个元素:绑定事件的这个元素
                      多个元素绑定事件this->当前元素:当前触发事件的元素
   

运算符和表达式

位运算

            左移:m<<n,读作m左移了n位,翻译:m*2的n次方
            右移:m>>n,读作m右移了n位,翻译:m/2的n次方
            缺点:底数只能2
            

赋值运算

            +=  -=  *=  /=  %=
            一个操作两件事,先计算,再赋值回去
               
            i++;//递增:每次只会固定+1
            i+=1;//累加:每次+几由我们程序员自己决定
            i++ === i+=1 === i=i+1;
            
            鄙视题:++ii++的区别:
                   单独使用,放前放后无所谓,效果一样。
                   但是如果参与了别的表达式,变量中的值都会+1
                   前++返回的是加了过后的新值
                   后++返回的是加了之前的旧值
                   

逻辑运算——特殊:短路逻辑

            如果前一个条件,已经能够得出最后结论了,则不看后续
            
            &&短路:如果前一个条件满足,才执行后续操作,如果前一个条件不满足,则不管后续操作
            目的:简化【简单的】分支:1、一个条件一件事满足就做,不满足就不做 if(){}
                                    2、操作只能有一句话
                       条件&&(操作);
            举例:原来:if(money>=500){money*=0.8};
            现在:money>=500&&(money*=0.8);

            ||短路:浏览器兼容:二选一操作 
                    e=e||window.event;
            

三目运算

            简化if...else	简化if...else if...else
            语法:
                1、条件?操作1:默认操作;
                2、条件1?操作1:条件2?操作2:条件3?操作3:默认操作;

            特殊:
                 1、只能简化简单的分支 - 操作只能有一句话
                 2、默认操作不能省略

            总结:
                if	      ===  &&短路
                if else         ===  三目
                if else if else ===  三目