JavaScript学习 --- 第一周

151 阅读16分钟

初识JavaScript

一 . 概念

   JavaScript是一门运行在浏览器端解释型弱类型面对对象脚本语言;

  • 运行环境:(浏览器端)打开浏览器就可以运行,浏览器内部有自带的js解释器

  • 编译类型:
    1. (解释型--自由)编译前不检查语法错误,有没有错误,都直接运行,运行到错误那一行停止运行并报错;
    2. (编译型--严格)编译前先检查语法错误,若有错误,直接不运行;

  • 语言类型:
    1. (弱类型--自由)声明变量的数据类型由数据本身决定,用关键字 var x = 1;
    2. (强类型--严格)声明变量的数据类型由关键字决定,如:int i=0;/ strig str="abc";

  • 面向对象:*
    对象的含义是指具体的某一个事物,即在现实生活中能够看得见摸得着的事物。在面向对象程序设计中,对象所指的是计算机系统中的某一个成分。在面向对象程序设计中,对象包含两个含义,其中一个是数据,另外一个是动作对象则是数据和动作的结合体。对象不仅能够进行操作,同时还能够及时记录下操作结果。

二 . js组成部分

  • ECMAscript:核心语法ES3、5、6、7、8、9、10、11、12;
  • DOM:Document Object Model,文档对象模型
  • BOM:Browser Object Model,浏览器对象模型

三 . HTML页面中 js使用语法

 -     <script>//js代码段</script>
 -     <script src="js文件路径">//这里不写代码</script>

四 . js输出方式

  • 控制台打印输出日志 ---- console.log("输出内容"); //推荐

  • 页面文档输出日志 ---- document.write("输出内容");
    //不推荐,因为输出之后会将原页面的所有内容都替换掉,不可取

  • 警示框输出 ---- alert("输出内容");
    //alert输出多个变量, 变量类型相同记得+"",变量类型不同,拼接写+全部转字符串,写逗号会只识别第一个变量,上面两种逗号和加号都行
    //缺点:在浏览器中偶尔会把页面卡成白板,让页面内容消失。

五 . 变量 / 常量

  • 变量:用于存放代码中需要反复使用/修改操作的数据,创建后可以修改
    声明:var 变量名 = 值;
    例如:var x = 1;
    注意:
    1 . 变量名命名要遵循:
    (1)不能以数字开头
    (2)语义化命名,见名知意
    (3)规范命名(驼峰/脊柱)
    2.

  • 常量: 用于存放代码中需要反复使用/无需修改的数据,创建后不可修改
    声明:const 常量名 = 值;
    例如:const pi=3.1415926;

六 . 数据类型

1 . 原始/基本/值 类型
(typeof(变量);//查看值类型)

数据类型取值控制台输出颜色例子转换为数字类型作用
数字 ( number )无数个蓝色var x = 100;100
字符串 ( string )无数个黑色var y="abc";NaN
布尔类型 ( boolean )true / false蓝色var bool = true;1 / 0存放布尔值用于判断操作
空值 ( null )null灰色var x = null;NaN唯一作用是释放内存
未定义 ( undefined )undefined灰色未赋值变量的默认值没有用

七 . 运算符

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

% : 取余,俗称模,两数相除取余数,作用:(1)余数判断奇数偶数(2)取出数字的后n位

  特殊 :

  • (1)算术运算符带有隐式转换:会默认将符号两边的数据类型都转为数字类型

    true ---- 1
    false ---- 0
    null ---- 0
    undefined ---- NaN
    "1000" ---- 1000
    "100px" ---- 要用parseInt();强制转换
    
  • (2)+ 号两边若出现字符串,会将两个数据都隐式转换成字符串类型,操作变成字符串拼接

2 . 比较/关系运算符( > / < / = / <= / <= / != / === / !==)(结果一定是布尔值)

  特殊 :

(1)如果参与比较的是字符串,就会依次按位pk字符串的ASCII码(十进制) 或者 Unicode码(十六进制);( 0-9 < A-Z < a-z < 汉字)
(2)NaN参与任何关系运算结果都是false,包括和他自己 NaN (Not a Number) 不是一个数字,却是number类型

!isNaN();判断是否是数字类型,返回布尔值

(3)undefined == null //true

3. 赋值运算符 += -= *= /= %=
    i+=5; ----> i=i+5;
4. 自增自减运算符 ++ --

面试题:前++和后++区别; i++/++i

1. 如果不参与表达式运算,那么两者没什么不同
2. 如果参与表达式运算, i++返回的是旧值用于参加运算,就是i的值
                     ++i返回的是新值用于参加运算,是i++后的值
  
  比如i=5i++ + ++i == 12
           5   +  7
5. 逻辑运算符(&&与、||或 、!非)
        (1)&& 全真才真,一假为假
        (2)|| 一真为真,全假才假
        (3)! 布尔值取反
6. 位运算(<<左移 >>右移)
         (1)左移  m<<n(m左移n位)--- m * 2的n次方
         (2)右移  m>>n(m右移n位)--- m / 2的n次方
         
         
         

七 . 程序的流程控制语句 ( 顺序结构,分支结构,循环结构 )

( 1 ) 顺序结构:默认 ---- 从上到下依次执行语句
( 2 ) 分支结构:(3种)通过条件判断,来决定执行哪一个代码段

1 .if...else 分支

  • ( 1 ) if (条件) { 操作; }
    //一个条件,一个操作,满足就做

  • ( 2 ) if ( 条件 ) { 操作1; }
    else { 默认操作; }

    //一个条件,两个操作,满足做操作1,不满足就做默认操作

  • ( 3 ) if ( 条件1 ) { 操作1; }
    else if ( 条件2 ){ 操作2; }
    ......
    else{ 默认操作; }

    //多个条件,多个个操作,满足哪个条件做哪个操作,都不满足就做默认操作

2 . switch...case 分支

  - ( 1 ) 语法:<br>
  -     switch(变量/表达式){
                 case1: 值1  //变量 == 值1 的时候执行操作1
                      操作1;
                      break;
                 case2: 值2
                     操作2;
                     break;
                 case3: 值3
                     操作3;
                     break;
                     .......
                 case n: 值n
                     操作n;
                     break;
                 default:
                     默认操作
                }
               //特殊 : 1)如果不加break,默认只要满足一个case就会把后续操作全部做完,最后一步default执行完就退出了,可以不加break;
               (2case在做等值比较时不带隐式转换,注意数据类型!
               (3)中间多个case值一样可以省略不写;
               (4default可以不写但是最好不要,如果条件不满足就会无事发生。

面试题:if 和 switch 分支的区别?

类型优点缺点
if可以做范围判断执行效率,因为是范围判断
switch执行效率,因为是等值比较必须知道结果是什么才可以设置比较值

3 . 三目运算符 --- 简化分支

(1)单条件语法:条件 ? 操作 : 默认操作 ;
//相当于if...else

(2)多条件语法:条件1 ? 操作1 : 条件2 ? 操作2 :.....:默认操作;
//相当于if...else if...else;

特殊:建议条件少的用,条件多用前两种,默认操作不能省略,否则报错。

( 3 ) 循环结构:(3种)通过条件判断,来反复执行相同或者相似的操作

循环三要素 :
1. 循环条件 : 开始到结束循环的次数 (比如 var i=0;i<10;)
2. 循环体 : 需要循环的代码段
3. 循环变量 : 记录当前正在做第几次循环,做完就自增(i++)
循环执行原理 :

  1. 创建循环变量
  2. 判断循环条件,满足执行循环体,不满足则不执行
  3. 执行一次后仍然满足循环条件,则再次循环
  4. 直到不满足循环条件再退出

1 . for 循环

语法 : for ( var 循环变量=值;循环条件;循环条件变化; ) { 循环体; }
特殊 :
( 1 ) 定义循环变量时还是要var一下,否则全局污染
( 2 ) 死循环的运用 : for( ; ; ){ 循环体; (判断后break;) } , 用于不知道循环次数的循环,满足条件后要搭配break跳出循环,否则会卡死

2 . while 循环

语法 :
var 循环变量 = 值 ; //一般是0或1
while ( 循环条件 ) {
循环体;
循环变量变化; // i++;
}

特殊 :
(1) 死循环 : while( true/1 ), 必须搭配 break / continue 使用
- break : 退出循环 , 不再执行循环
- continue : 退出本次循环 , 若符合循环条件 , 下一次接着循环

面试题 : for 循环 和 while 循环 的区别?
   答 : 原理上二者没有区别,但是一般来说
   
        确定循环次数 ------ 大部分用for
        不确定循环次数 ---- 用死循环 , 记得break

3 . do...while() 循环 语法 :
var 循环变量 = 值 ; //一般是0或1
do{
循环体;
循环变量变化; // i++;
}while ( 循环条件 )

面试题 : while 循环 和do...while 循环 的区别?
   答 : 区别在第一次执行
   
   while ---- 第一次执行,条件不满足就不会执行
   do...while ---- 第一次执行,先执行一次再判断条件,所以即使条件不满足,也会执行一次

八 . 强制数据类型转换 / 显示数据类型转换

1. 转字符串类型 ( String();//万能 )
方法:
( 1 ) var str = x . toString ( ) ;
//toString 方法,只能面对对象使用,x不能等于undefined 和 null

( 2 ) str =String(x);

( 3 ) x + ""
//利用 + 符号的隐式转换 ,加上一个空字符串,两边都转化为字符串类型, x + ""

2. 转数字类型 ( Number();//万能 )
方法:
  ( 1 ) parseInt(str/num);
  //parse(解析) 字符串或数字转为整数类型
  //原理 : 是从左到右依次解析,遇到非数字字符就停止转换,第一个都不认识,就是NaN
  //例如 : parseInt("1000px"); ---- > 1000

  ( 2 ) parseFloat(str/num);
  //字符串或数字转为浮点数类型,原理同上,只认识第一个小数点,遇到第二个就停止转换

  ( 3 ) x-0 x*1 x/1
  //利用运算符号的隐式转换 ,两边都转化为数字类型, 加号特殊不用

3. 转布尔类型 (Boolean();//万能)
特殊 : 只有6个值转换为布尔类型后取 false 值 , 其余都取 true
  0 / "" / null / undefined / NaN / false

函数 ( Function )

一 . 概念 :

先预定义好一个函数/方法 , 之后可以反复调用的代码段 , 创建好不执行 , 调用才执行

二 . 函数如何使用 :

( 1 ) 定义 / 创建 / 声明 一个函数
1 . 直接声明 :

  •  function 函数名(形参列表){
                   操作;
                   return 返回值/结果; 
                   //没有形参也可以返回值到全局,在全局用变量接住就可以继操作
               }
    

1 . 直接量方式 :(不推荐)

  •    var 函数名 = function(形参列表){ // 函数名相当于变量名
                      操作;
                      return 返回值/结果; 
                     }
    

( 2 ) 函数的调用

1 . 函数中直接调用 : 函数名();
2 . HTML页面中调用 : 给元素绑定onclick事件 , 再调用 <elem onclick="函数名()"></elem>
3 . return 的使用 :
  全局想用局部的私有的东西 , 就可以返回到全局 , 再用变量接住 ,就可以使用了.
var 变量 ( 用于接住返回结果 ) = 函数名 ( 实参列表 ); //将实参传进函数进行操作

注意 :
1 . return的本意是退出函数并返回一个值 , 本身没有保存值的功能 , 所以需要用一个变量接住才能使用;
2. 省略 return , 也会默认返回一个 undefined ;

三 . 函数的作用域 :

  1. 全局作用域 : 全局变量 / 全局函数 , 在页面的任何一个位置都可以使用 , 包括局部;
  2. 局部作用域 : 局部变量 / 局部函数 , 只能在局部内可以使用 , 但是局部使用未var就直接赋值的变量会造成全局污染 ;

  !! 带来变量的使用规则 : 局部内优先使用局部的变量,局部没有就找全局要,全局也没有,就会报错undefined,如果在局部对变量直接赋值,就会造成全局污染

  !! 全局污染 : 若在函数中对未声明的变量直接赋值,就会导致全局本身没有这个变量,但是被函数作用域给添加上了,会增加内存,后续要是全局使用了这个变量会造成污染

四 . 声明提前 : ******** 开发不使用,只出现在笔试

1. 规则 :
在程序正式执行之前,会把 var声明的变量function声明的函数集中定义作用域最顶端, 但是赋值会留在原地!

2. 优先级 :
变量 > 函数
!! 特殊 : 直接量声明的函数当做变量处理

五 . 方法重载 :

1 . 规则 :
  相同的函数名,根据传入的实参的不同来判断自动选择相应的函数去执行,但是js中不支持,写在后面的同名函数会覆盖前面是的函数 ;

2 . js中的重载 :
  js中,在函数内部自带 ( 不用用户创建 ) 了一个arguments对象( 类似数组对象 ) ,这个arguments类数组对象,哪怕函数没有写任何形参,他也会接住所有的实参,所以这个默认length = 0 ;

!! arguments的使用方法 :
(1)通过实参在实参列表中的下标,来获取某一个实参 : arguments [ i ];
(2)通过length判断传入了几个实参 :arguments.length ;
(3) 在函数内部,通过对传入实参的判断来实现分支操作 , 从而在函数内部实现重载 ;

数组

1. 特点 : 一个变量保存多个数据,数组都是线性排列,每个元素都有一个前驱元素,一个后继元素 ,数组中每个元素有自己的位置叫下标 ,从0开始

2 . 创建数组:2种

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

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

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

4、后续添加/替换元素: 数组名[i]=新数据;
如果下标处没人则为添加,如果下标处有人则为替换

5、数组具有三大不限制
1、不限制元素的类型
2、不限制元素的长度
3、不限制下标越界 (缺点)
如果获取元素时 ,下标越界 ,返回的是一个undefined 如果添加元素时 ,下标越界 ,会得到一个稀疏数组,如果我们搭配上我们学过循环去遍历获取每个元素,会得到很多很多undefined ;

问题:自己数下标,难免会数错,导致我们下标越界
6 .数组属性length :
数组中有一个唯一的属性:length
语法:数组名.length
作用:获取到数组的长度,长度是从1开始的

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

7 . 遍历数组

往往很多情况需要拿出每个元素来进行 相同 或 相似的操作 --- 搭配上循环

遍历固定公式:

for(var i=0;i

arr[i];//当前次元素

}

DOM

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,只会找到第一个
			3、记住控制台输出的样子,这个样子才叫做一个DOM元素/节点/对象,才可以下午去做操作
			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、外部样式表 - 一阶段做开发用的都是外部样式表
	
	二阶段我们就要用js来操作【内联样式】
		1、不会牵一发动全身
		2、优先级最高

	获取样式:elem.style.css属性名;
	设置样式:elem.style.css属性名="css属性值";
	特殊点:
		1、css属性名,有横线的地方,去掉横线,变为小驼峰命名法
			border-radius     -----  borderRadius
		2、小缺陷:获取时,我们只能获取到内联样式,因为我们目前学的就是内联样式的操作

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

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