JavaScript-week1

178 阅读15分钟

JavaScript概述

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

javascript解释器:

1.浏览器自带js解释器
2.独立安装一个js解释器-node.js

编译型

运行程序之前,需要检查语法是否正确,如果不正确直接不允许运行,比如:java、c、c++、c# - 更加严格

解释器

运行程序之前,不要检查语法是否正确,直接运行,碰到错误就会停止运行,比如:javascript、php、node.js... - 更自由

JS特点

1.代码可以用任何文本编辑器编写:vscode、Hbuilder、记事本..
2.解释型语言,无需编译。
3、弱类型语言:不需要进行规定,你想放什么就放什么。变量的数据类型是由值来决定的

面向对象语言

程序员眼看任何东西都是一个对象:有了一句话叫做 万物皆对象。
以后经常会见到一种语法:xx.xx 或 xx.xx()
一切东西都有自己的属性和方法:对象名.属性名;
			   对象名.方法名();

js作用

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

JavaScript使用

使用方式

1.HTML页面上写一个标签:-临时测试/上课用
        <script>
              js代码
        </script>
        
2.创建一个xx.js文件,在里面书写js代码,最后在HTML页面引入
    <script src="xx.js文件路径">//此处不再支持书写代码了</script>

JS的调试语句

代码运行期间,如果碰到错误,会报错,但是后续代码就不会执行了,甚至如果只是逻辑错误不是语法错误,那并不会报错,我们需要一个方式去帮助我们找到错误何在。

1、在控制台输出日志:console.log(想要输出的东西);//打桩输出,疯狂打桩。
2、在页面上进行输出:document.write(想要输出的东西); - 要不得,如果绑定上了事件,会将页面上所有的内容全都替换掉。
3、弹出框显示:alert(想要输出的东西); - 会卡主整个页面,必须关闭后用户才能看到HTMLCSS

JS的语法规范

是严格要求区分大小写的,不能乱写。
比如:
        console.log();//正确写法
        console.Log();//错误写法

JS注释

作用:提示程序员
单行注释://
多行注释:/****/

变量

变量:值是可以改变的
何时使用:只要你以后需要经常使用的数据,都要先保存在一个变量中,以后使用变量名,相当于就是在使用变量的值了。
语法:var 变量名 = 值;
比如:var age=128;
特殊:
1、=:赋值符号,将=右边的数据放到=左边的变量名之中。
2、如果只声明/创建/定义了,没有赋值的话,默认值为undefined(是一个垃圾,没有任何用处),记得一定要赋值。
3、取变量名不能随意,尽量的见名知意。
4、如果创建多个变量,中间的var可以省略,中间的;换为,,最后一个依然是;结束。
5、面试题:如果是一个未声明的变量直接使用,会报错
          如果是一个声明过的变量但是未赋值,会undefined6、name变量名是一个关键字,里面只能放入字符串,哪怕你放的不是字符串,也会悄悄变成一个字符串    

常量

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

算术运算符

+ - * / %
其实前四个运算符和小时候一模一样
但是特殊:
1、%:取余,俗称模,两个数相除,但是不取商,而取余数
            5%2 ==> 1
            2%5 ==> 2
            64%8==> 0
            7%2 ==> 1
       作用:1、*判断奇偶性
           num%2;//结果为0说明是一个偶数,结果为1说明是一个奇数
            2、获取某个数字的最后n位
                1234%10 ==> 4
                1234%100 ==> 34
                1234%1000 ==> 234
2、***隐式转换:悄悄的转换,数据类型会发生变化,我们程序员看不见。
    常理来说只有数字才能参与算术运算,但是其实字符串也可以,一定要切记以下几句话:
        *****默认运算符左右两边都会悄悄的变成一个数字,在运算。
        特殊:1、+运算,只要碰上一个字符串,则都变为字符串,+运算也不再+运算,变成了拼接字符串操作。
             2、-*/%运算,有字符串也可以转为数字,但是必须是纯数字组成的字符串才可以,只要包含了非数字字符,结果则为NaN(垃圾)
             NaNNot a Number:不是一个数字,但是确实是数字类型 - 不是一个有效数字,不在三界之中。
             NaN参与任何算术运算结果仍为NaNNaN参与任何比较运算结果都为false

JS中数据类型

1、原始/基本/值类型:51String - 字符串,取值有无数个,必须写"" 或者 ''2Number - 数字,取值有无数个,直接写个数字就行。
    3Boolean - 布尔,取值只有两个,truefalse,多半都是用于判断比较。
    4Undefined - 取值只有一个默认值undefined,没有任何用处 - 祖师爷犯的一个错误。
    5Null - 空,取值只有一个null,作用:释放变量、内存,节约内存空间。

2、引用/对象类型:11个,每个对象都有很多的属性和方法等待我们去学习

扩展

1、弹出一个用户输入框:var user=prompt("提示文字","默认值");
 2、分支结构:根据条件的不同,选择一部分代码执行操作
		1、一个条件 一件事,满足就做,不满足就不做
			if(条件){
				操作
			}
		
		2、一个条件 两件事,满足就做第一件,不满足就做第二件
			if(条件){
				操作
			}else{
				默认操作;
			}

		3、多个条件多件事,满足谁就做谁
			if(条件1){
				操作1
			}else if(条件2){
				操作2
			}else if(条件3){
				操作3
			}else{
				默认操作;
			}
                 注意:1else if你想写几句就写几句
		      2、最后的else其实也可以省略,但是如果条件都不满足的话则什么不会执行 - 不推荐,什么都不执行相当于我们的分支白写了
		      3、分支结构只要满足一个就不可能再走另一条路了

数据类型转换

javascript是弱类型语言,数据类型都是由数据来决定的。
对于不同数据类型的运算时,数据类型会进行转换:
                                            number+number=number
                                            number+string=string
如果你喜欢查看数据类型:typeof(需要检查的人);

算术运算隐式转换:

自动转换,悄悄的,我们程序员是看不见的。

其实,只要是算术运算给就一定带有隐式转换,默认会将左右两边转为数字,再运算。

特殊:
        1、+运算,如果碰到了一个字符串,那么左右两边都会悄悄转为字符串,再拼接。
        2、-*/%,就算是字符串也可以转为数字,但是不需要是纯数字组成的才可以,只要包含了非数字字符,则为NaN3、某些类型转为数字的结果
            true->1
            false->0
            undefined->NaN
            null->0
            "100"->100
            "10abc0"->NaN
        4NaNNot a Number,不是一个数字,但是确实是数字类型,理解为是一个无效的数字。
           缺点:
                   1NaN参与任何算术运算结果仍为NaN2NaN参与比较运算结果都为false。

问题:我们没有办法使用普通的比较运算来判断x是不是NaN
      解决:个人更爱反用:
          !isNaN(x) - 判断x是不是一个有效数字
          true->说明是一个有效数字
          false->说明是一个NaN
                   

强制/显示转换

隐式转换的结果可能不是我们想要的,我们程序员可以手动调用某些方法,进行数据类型的转换后,再运算

 1、转为字符串:
    语法:var str = x.toString();//x不能是undefined和null,因为undefined和null不能使用.操作.
    此方法不重要,页面上获取来的所有的数据默认都是字符串
 2、*转数字:3个方法
    *1var num=parseInt(str/num);  parse->解析 Int->整型/整数
     原理:从左向右依次读取每个字符,进行转换,碰到非数字字符就停止,而且不认识小数点,如果一开始就碰到了不认识的字符,结果为NaN
                        console.log(parseInt(35.5));//35
                        console.log(parseInt("35.5"));//35
			console.log(parseInt("35hello5"));//35
			console.log(parseInt("hello35"));//NaN
			console.log(parseInt("35px")+100+"px");//35
			console.log(parseInt("35px555abc"));//35
			console.log(parseInt(布尔、undefinednull));//NaN
    *2var num=parseFloat(str);  parse->解析 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("px35.5px"));//NaN
			console.log(parseFloat(true));//NaN
     3Number(x);//x是万能的,任何人都可以转为数字
                  //垃圾,因为此方法完全就是隐式转换,还不如对着x *1 /1 -0,绝对不要手动使用
                  
总结:
     1、只要页面上带有单位的数字,我们都可以用parseXXX来去掉单位变为数字
     2Number何时都不用

函数

3次才能完整的学习完毕,函数是第一等公民的地位。
js里面的函数 - 完成了一个xxxxxxxxxxx的功能。

1、什么是函数:也称为方法,需要【预定义】(提前创建好)后,可以【反复使用】的【代码段】(里面可以放若干代码)
2、创建函数并且调用函数:
            第一步:
            创建:function 函数名(){
                            若干代码段
            }
            
            第二步:
            调用:2种方式
            1、直接在js里面写 函数名();程序员写几次就会执行几次
            2、绑定在页面的元素上,让用户来出发,用户触发一次就会执行一次
            <elem onclick="函数名();"></elem>
3、以后何时使用函数呢?
    1、打开页面不希望立刻执行。
    2、希望用户/程序员来触发。
    3、希望能够被反复执行。
    4、本身就是一段独立的功能体:暂时理解为我们的每一个作业就是一个地理的功能体。
    5、以后要尽量的将每个功能封装为一个函数,函数是第一等公民的地位。而且函数中的变量会自动释放。
4、带有参数的函数
    电饭煲->function函数
    功能:把什么东西煮熟
    原材料->参数:米饭
    1、创建带参数的函数:
        形参:就是一个变量名,只不过这里的变量名不需要var,并没有保存真正的值,形式参数,简称形参。
        function 函数名(形参,...){
                函数体;
        }
    2、调用带参数的函数:
        实参:实际参数,这个变量名所保存的值。
        函数名(实参,...)
    
    一个函数可以执行相似的操作:
        比如:实现任意两个数相加:
                function add(a,b){
                        console.log(a+b);
                }
                add(1,2);
                add(2,4)
        注意:带参数的函数,在调用时,传入的实参的顺序和个数都要一一的和形参对应上。

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

分支结构

1、代码中流程控制语句:31、顺序结构:
            默认结构,代码从上向下一步一步执行的。
        2、分支/选择结构:
            根据条件,选择一部分代码去执行。
        3、循环结构:
            根据条件,判断你是否需要再一次重复的执行某一些代码。
2、比较运算符:> < >= <= == !=
        作用:比较判断/条件中出现。
        结果:以上六个运算符,结果一定是一个布尔值。
        其实比较运算符也具有隐式转换,大部分情况下依然会转为数字在比较大小。
3if结构:
        1、一个条件一件事,满足就做不满足就不做
                if(条件){
                        操作
                }
        2、一个条件2件事,满足就做1不满足就做2
                if(条件){
                         1
                }else{
                         2
                }
        3、多个条件多件事,满足谁就做谁
                if(条件1){
                         1
                }else if(条件2){
                         2
                }else{
                         3
                }
拓展:逻辑运算符:&&(与、并且) ||或 !非
        &&:只有全部条件都满足,最后结果才为true。
            只要有一个条件为false,结果就为false。
        
        ||:只有全部条件都不满足,最后结果才为false。
            只有一个条件为true,结果就为true。
         !:颠倒布尔值
                 !true->false
                 !false->true
                 !!!true->false

循环结构

1、问题:程序员打印输出10000局hello world
        console.log("1hello world")
        ...
        console.log("10000hello world")
2、什么是循环?
    1、吃饭
    2、睡觉
    3、做作业
    4、上班上课
    5、活着
    6、地球公转自转

循环

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

while循环

语法:
    var 循环变量 = 几;
    while(循环条件){
            循环体;
            循环变量的变化;
    }
原理:先判断循环条件,如果条件为真,则执行一次循环体中的语句,然后再一次判断循环条件,如果为真,则再执行一次循环体中的语句。...直到循环条件为假,才会退出循环。

强调:循环是一次一次执行的,只不过速度很快,而且循环没结束之前,会卡住后续代码。

死循环:停不下来的循环,多半用于不确定循环次数的时候
        while(ture){
                循环体;
        }

循环流程控制语句:死循环多半都要搭配上一个:退出循环:break

扩展

    随机整数公式:parseInt(Math.random()*(max-min+1)+min);

for循环

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

特殊:
    1、死循环:for(;;){循环体} - 两个分号,一个都不能少。
    2、循环变量处其实可以创建多个变量。
    3、也支持break

总结:

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

数组

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

创建数组

两种方式:
1、直接量方式:
    var arr = [];//空数组
    var arr = [数据,数据,...];
2、构造函数方式:
    var arr = new Array();//空数组
    var arr = new Array(数据,数据,...)

访问数组

1、获取数据
        数组名[下标]
   特殊:1、下标越界,获取到的是一个undefined;
2、添加数据
        数组名[下标]=新数据;
   特殊: 
   1、如果下标处已有元素,则为替换。
   2、如果下标越界,会导致你的数组变成一个稀疏数组,中间就会出现很多的undefined,而且下标也不再连续。
   
3、结论:数组具有3大不限制:
        1、不限制元素的长度。
        2、不限制元素的类型。
        3、不限制下标越界。

数组对象

三个固定套路:
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];//当前次获取到的元素
        }

DOM树

DOMHTML看做了是一个倒挂的树状结构,但是树根并不是你们理解的HTML标签。
*树根:是一个document对象,document对象不需要我们程序员创建,由浏览器的JS解释器创建,一个页面只有一个document。

作用:提供了一些属性和方法,可以让我们程序员去操作整个DOM树(增删改查每一个DOM节点)。

DOM节点:一个标签、文本、属性、元素

查找元素

1、通过ID查找元素

var elem = document.getElementById("id值");
在当前DOM树中,根据元素的id,过去具体的DOM节点。
返回:找到了,返回对应的元素
     没找到:null
特殊:
1、如果页面上有多个重复的id,只返回第一个
2、此方法找到的是单个元素-DOM节点是可直接用于操作的。

2、通过标签名查找

var elems = documen/已经找到的父元素.getElementByTagName("标签名");
在当前DOM树中,根据标签名获取元素们。
返回:找到了,返回一个DOM集合
      没找到,空数组。
特殊:
1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部。
2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素。

3、通过class名查找

var elems = document/已经找到的父元素.getElementsByClassName("标签名");
在当前DOM树中,根据标签名获取元素们。
返回:找到了,返回一个DOM集合
      没找到,空数组
特殊:
1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部
2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素

通过节点之间的关系查找

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

操作元素

<标签名 属性名="属性值" style="样式">内容</标签名>
内容:
1、innerHTML属性:获取 或 设置 某个元素的内容,并且可以识别标签
        获取内容:elem.innerHTML;
        设置内容:elem.innerHTML="新内容";
2、innerText属性:获取 或 设置 某个元素的文本,不能识别标签
        获取内容:elem.innerText;
        设置内容:elem.innerText="新内容";
以上两个属性,是为双标签准备的

3、value属性:专门为单标签(input)操作内容准备的
        获取内容:input.value;
        设置内容:input.value="新内容";

操作属性

属性:什么是属性:HTML属性:id、class、title、alt、style、href...只要是放在HTML标签上的都是一个属性。
        获取属性值:elem.getAttribute("属性名");
        设置属性值:elem.getAttribute("属性名","属性值");
以上两个方法有点繁琐-但是无敌
能够简化:
        获取:elem.属性名;
        设置:elem.属性名=属性值;
缺陷:
    1、不能操作自定义属性,只能操作标准属性;
    2classES6升级为了一个关键字,所以想要写class换为了className;

操作样式

1、css定义的方式:31、内联样式表
        2、内部样式表
        3、外部样式表

2JS操作内联样式表的好处:
        1、优先级最高,写的JS样式必定生效
        2、一次只会操作一个元素,不会牵一发动全身

3、语法
        获取:elem.style.css属性名;
        设置:elem.style.css属性名="css属性值";

特殊:
        1、css属性名,要把有横线的地方,换成小驼峰命名法
        2、获取的时候,不能股哦去样式表中的样式

元素绑定事件

单个元素:
    elem.onclick = function(){
            操作;
            this->单个元素绑定事件,this-elem绑定事件的这个元素
        }
多个元素:
    for(var i =0;i<elems.length;i++){
            elems[i].onclick = function(){
                操作
                this->多个元素帮i的那个事件,this->当前触发事件的元素
            }
    }
总结:
1、一切的获取都是为了判断。
2、一切的设置都是为了修改。
3、千万不要对着一个集合做操作,要么遍历拿全部,要么下标拿一个。