一、初识JavaScript
1.什么是JavaScript? JavaScript是运行在js解释器的解释型、弱类型、面对对象脚本语言。
2.JS解释器:
1、浏览器自带js解释器,不需要安装可以直接使用
2、后续使用Node.js还会安装一个独立的js解释器
3、编译型与解释型
编译型:运行之前需要检查语法是否正确,如果不正确直接不能运行,比如:Java、c、c++、c#...
解释型:运行之前不需要检查语法是否正确,直接运行,如果碰到错误就会停止后续代码,比如:JavaScript、php
4、弱类型:由 数据 决定了 数据类型是什么 - 比如javascript
1 - number数字
"1" - string字符串
强类型:由数据类型 决定了 你这个变量能保存什么数据 - 比如:Java
5、面向对象:以后你会经常见到这种语法
对象名.属性名;
对象名.方法名();
万物皆对象,比如:人(属性:身高、体重、姓名、性别、年龄)、杯子、电脑、轮播、购物车
(方法:吃饭、喝水、玩游戏)
6、js的特点:
1、代码可用任何编辑器编写(HBuilder、VScode、atom、webstorm、记事本....)
2、解释型、弱类型、面向对象
3、用途:
1、实现所有css完成不了的效果
2、和服务器端进行交互沟通 - ajax(j:JavaScript)
2、JS的使用:
1、如何在html上书写js:2种
1、在HTML页面上写一个script标签,在里面编写你的js代码
2、正式开发中 - 在外部创建一个js文件,里面编写你的js代码,记得要引入
2、***输出的方式:3种 - 作用:测试语句,打桩输出,找错的方式
1、console.log(想要输出的内容) - 在F12的控制台console查看 - console控制台 log日志
2、document.write(想要输出的内容) - 在页面body上输出 - document当前文档 write写入,缺点:只要搭配上点击事件,则会替换掉当前页面原有的所有内容
3、alert(想要输出的内容) - 在一个弹出警告框上输出,缺点:会卡住整个页面(只能看到一个白板)
3、***变量:变量的特点数据是可以改变的
硬盘:存储文件、数据 - 外部存储器
CPU:中央处理器 - 用于计算
内存:是【临时保存】程序运行中,所需要用到的数据,变量其实就可以说是一个内存空间
内存空间:保存数据的一个地方
内存地址:内存空间的一个门牌号,如果内存地址过长,不方便记忆
语法:var 变量名=值;
以后只要反复使用的数据,都要提前保存成一个变量,方便以后使用
特殊:
1、变量名不是随意的
1、不能以数字开头
2、不能使用关键字
3、尽量要见名知意
千万不要:会导致这段代码,以后没人看得懂,没有知道这个变量到底用来干什么了
尽量要用英文单词命名,不会就翻译,顺便多学点单词
2、其实var 变量名;这句话就代表此变量已经创建好了,但是未赋值,默认值为undefined
3、赋值符号:=,把等号右边的数据保存到等号左边,左边一定是一个变量名
4、name其实是一个关键字,不管你保持什么数据类型,最后都会隐式(悄悄的)变成一个字符串
5、常量:一旦创建了就不允许修改了 语法:const 常量名=值;
6、运算符:
1、算术运算符:+ - * / %
%:读取取余或者模,m%n,翻译:m除以n,不取商,而取除不尽的余数
%作用:
1、*判断奇偶性 num%2==0 偶数 num%2==1 奇数
2、获取一个数字的后n位:%10 %100 ...
3、控制一个结果永远不超过几
num%5 -> 结果永远不会超过5
***算术运算具有隐式转换,默认为转为数字,再运算
特殊:+运算,如果碰到了一个字符串,那么两边都会悄悄的转为一个字符串,然后+运算也不再是+运算,变为拼接操作
7、数据类型:2大类:
1、原始/基本/值类型:5个
1、String - 字符串,取值有无数个,必须 "" 或 '' 包裹
2、Number - 数字,取值有无数个,不需要任何包裹
3、Boolean - 布尔,取值只有2个,true和false,代表真(对)和假(错) - 判断/比较的时候出现
4、Undefined - 取值只有一个:undefined,变量未赋值时的默认值,而且没有任何用处
5、Null - 取值只有一个:null,空,释放内存/变量
2、引用/对象类型:11个对象(属性和方法)
*只要页面上的一切数据(文字、样式、用户输入的东西),数据类型都是一个字符串
1、***数据类型转换:
JavaScript是弱类型语言,由数据 决定了 数据类型是什么
对于不同数据类型的运算时,数据类型会进行自动转换:
number + number = number
number + string = string
如果你希望看到数据类型到底是什么:
console.log(typeof(变量))
1、*隐式转换:悄悄的进行数据类型的变化
算术运算符的隐式转换:
默认两边都会悄悄的转为是数字再运算
特殊:1、+运算,碰到一个字符串,两边都会悄悄的的转为字符串,再拼接起来
2、其他类型转为数字会为:
true->1
false->0
undefined->NaN
null->0
3、其实字符串也可以转为数字,但是前提必须是纯数字组成的字符串才可以,但凡包含了一个非数字字符则为NaN
"100"->100
"100px"->NaN
4、NaN:Not a Number直译为不是一个数字,但是确实发现他是数字类型(蓝色的)
全是缺点:
1、参与任何算术运算结果都为NaN
2、参与任何比较运算结果都为false
!isNaN(x); -> 判断x是不是一个有效数字,而且此方法会将x隐式转为数字
2、*强制/显示转换:隐式转换出来的结果不是我们想要的,程序员可以手动调用某些方法实现的数据类型转转
1、转为字符串:
var str=x.toString();//null和undefined不能使用,null和undefined不能使用.去做任何操作
绝对不会用:页面上的数据默认都是字符串
2、***转数字:
1、*var num=parseInt(str/num);parse解析Int整型:解析为一个整数
执行原理:专门为【字符串转为数字】准备,从左向右,依次读取每个字符,碰到非数字字符则停止,如果一来就碰到不认识的字符,则为NaN,不认识小数点
2、*var num=parseFloat(str); parse解析 Float浮点型:解析为一个小数
执行原理:几乎和parseInt一致,认识第一个小数点
//以上两种强制转换方法的值最好为字符串或者数字,true false undefined null在转换的时候均为NaN
3、Number(x);//万能的,任何人都可以转为数字,包括undefined和null都能转
//完全等效于隐式转换
parseXXX vs Number:
1、Number:不要手动使用
2、parseXXX:只要你希望字符串转为数字,必用,转整数还是小数需要自行判断
2、**Function的基础:
js的自定义函数:完成了一个的功能
1、什么是函数:也称之为方法,是一段被【预定义好】的,可以【反复使用】的【代码股】
2、创建函数以及功能:
语法:
function函数名0{
函数体:/若干操作
}
注意:函数定义好之后,不会立刻执行,只有再【调用】之后才会执行
3、调用函数:
1、直接在js里书写:函数名();需要程序员来操作,程序员调用几次就执行几次
2、交给用户,把函数绑定在页面元素上,用户来触发事件,触发几次就执行几次
3、什么东西适合封装在函数之中:
1、不希望打开页面立刻执行,可能是让用户来角触发
2、有可能被反复执行的代码,重复的代码
3、本身就是一段独立的功能体:你的每一个作业都是一个独立的功能体(以后你的每一个作业都可以封装为一个函数)
4、函数的地位在js里非常高,尽量的考虑能不能封装为函数,函数中的【变量会自动释放】
5、带参数的函数:
如何定义带参数的函数:
1、创建:
/形参列表其实就是变量,只不过这里的变量不需要关键字V,可以放多个,中间用,间隔,并没有保存住真正的值,所以是一个形式参数,简称为形参
function函数名(形参列表){
函数体:/若干操作
2、调用:
/调用带参数的函数,必须向里面传入实际参数,简称为实参
函数名(实参列表)
注意:
1、传入实参的顺序要和形参对应上
2、传入实参的个数要和形参对应上
3、函数不一定非要有参数:具体情况具体分析
4、如果你是固定的函数体操作,不需要传入参数-普通函数
3、**分支结构:
1、程序一共有三种结构:
1、顺序结构:默认结构,从上向下,依次执行每一行代码
2、分支结构:根据判断条件,选择一部分代码去执行(只会选择一条路走)
3、循环结构:根据判断条件,选择是香需要重复执行某一设代码
2、分支结构:
1、一个条件一件事,满足就做,不满足就不做
2、一个条件两件事,满足就第一件,不满足就做第二件
3、多个条件,多件事,满足谁就做谁
关系/比较运算符:> < >= <= == !=
以上6个运算符的结果一定都是一个布尔值:true、false
往往比较运算就会出现在分支、循环的条件之中
逻辑运算符:用于综合判断的
&&:并且、与 全部条件都为true,结果才为true,只要有一个为false,结果则为false
||或者 全部条件都为false,结果才为false,只要有一个为true,结果则为true
!:非-颠倒布尔值 !true - false !false - true
3、*循环结构
1、什么是循环:【反复执行相同或相以的操作】
循环特点:循环三要素
1、循环条件:开始、结束:重复执行多少次
2、循环体:循环的操作:要做什么
3、循环变量以及变量要变化
3、while循环:
语法:
Var循环变量=几;
while(循环条件){
循环体;
循环变量变化起来;
}
执行原理:先判断循环条件,如果条件为true,则会执行行【一次】循环体
然后再一次判断循环条件,如果条件为true,则会再执行【一次】循环体
直到循环条件为false,才会退出循环执行后续代码
注意:从宏观上来看,循环好像是一瞬间就完成的;但是从微观上来看,循环其实是一次一次执行的,不是同时执行的,只不过我们电脑的速度比较快
死循环:永远不会结束的循环~【不确定循环次数的时候】就使用死循环
while(true){
循环体:
}
但是死循环多半都要搭配上停止循怀语句:break;一起使用,要不然电脑都可能会死机
4、**for循环:
语法:
for(var循环变量=几;循环条件;循环变量的变化{
循环体;}
特殊:1、死循环:for(;;)操作
2、循环变量处可以用,隔开创建多个
while vs for:
1、while语法脏乱差,而且一般只适用于不确定循环次数的时候使用-死循环,非常少见,确实会见到
2、for语法非常舒服,而且一般只适用于确定循环次数的时候使用-大部情况都会使用for循环
小结:函数和循环都可以反复执行,他们的区别在哪里呢?
1、时机:
函数-多半都是用户来触发
循环-感觉上几乎是一瞬间就结束了
4、*****数组的基础:
1、问题:保存1000个人的姓名:
创建了1000个变量,意味着开辟了1000个内存空间,性能消耗较大,网页性能低下
解决:数组:多个元素/数据组成的一个集合,保存在一个变量名:一个变量可以保存多个数据
数组中的元素都是按照线性顺序排列:
除了第一个元素,每个元素都有唯一的前驱元素
除了最后一个元素,每个元素都有唯一的后继元素
***数组中每个元素都有一个唯一的位置序号,称之为【下标】,下标都是从0开始的,到最大长度-1
2、创建数组:2种方式
*1、直接量方式:var arr=[];//空数组
var arr=[数据,数据,....];
2、构造函数方式:var arr=new Array();//空数组
var arr=new Array(数据,数据,....);
3、访问数组中的元素:
数组名[下标];
4、追加/替换元素:
数组名[下标]=值;
当前下标有没有元素,如果有,则为替换,如果没有,则为追加
5、数组具有三大不限制:
1、不限制元素的类型
2、不限制元素的个数
3、不限制下标越界 - 不是优点了:
获取时,下标越界,得到undefined
追加时,下标越界,会导致数组变为稀疏数组,下标不再连续,如果有一天我们去遍历数组,我们必然会得到很多很多的undefined
6、数组唯一的属性:length - 长度
语法:数组名.length - 获取到此数组的长度
***数组的三个固定套路:
1、向末尾添加元素:arr[arr.length]=值;
2、获取倒数第n个元素:arr[arr.length-n];
3、缩容:删除倒数n个元素:arr.length-=n;
7、遍历数组:
把数组中的【每个元素取出来】【执行 相同 或 相似的操作】 - 循环数组得到每个元素
公式:
for(var i=0;i<arr.length;i++){ console.log(arr[i]);}//当前次元素
5、dom操作
1、JavaScript由三部分组成:
1、ECMAScript(ES3/5/【6】/7/8/9/10/11/12/13)
2、DOM - Document Object Model:文档对象模型 - 专门用于操作当前文档的(操作HTML)
3、BOM - Browser Object Model:浏览器对象模型 - 专门用于操作浏览器的(相对于DOM使用较少,但也有重点)
2、DOM概念:
DOM树:把HTML看作了是一个倒挂的树状结构,但是树根不是大家理解的html标签,而是document这个对象(属性和方法)
document对象是不需要我们创建的,浏览器的js解释器会自动创建,一个页面只有一个document对象
提供了很多属性和方法,等待我们去学习
注意:DOM会把页面上的所有元素、属性、文本、注释都视为是一个dom节点/dom元素/dom对象
3、获取元素:2个大方向
1、通过 HTML 的特点去获取元素
1、通过 ID:var elem=document.getElementById("id值")
特殊:
1、id如果重复了,只会找到第一个,id的唯一性
2、如果没找到,返回的是一个null
此方法不可依赖- 缺点:1、一次只能找一个元素,意味着只能操作一个元素 2、id留给后端用
2、*通过 标签名:var elems=document/parent.getElementsByTagName("标签名")
特殊:
1、返回的是一个类数组对象/集合,长得像数组,并不是数组,只不过也可以使用下标,也可以使用length,也可以遍历,有很多东西和数组是不一样的
2、*一个集合不能直接做操作,要么下标拿到某一个,要么遍历拿到每一个
3、如果没找到,返回的是一个空数组
4、此方法不一定非要写document,也可以是parent:是你已经找到的某个父元素
3、*通过 class名:var elems=document/parent.getElementsByClassName("class名")
用法完全等效于标签名用法
4、通过 关系 去获取元素:前提:先找到一个元素,才可以使用关系
父:elem.parentNode;
子:elem.children; - 集合
第一个儿子:elem.firstElementChild;
最后一个儿子:elem.lastElementChild;
前一个兄弟:elem.previousElementSibling
后一个兄弟:elem.nextElementSibling;
2、操作元素:
<标签名 属性名="属性值" style="样式">内容
1、内容:
1、*innerHTML - 内容能够识别标签
获取:elem.innerHTML;
设置:elem.innerHTML="新内容";
2、innerText - 不能够识别标签,只认识纯文本
获取:elem.innerText;
设置:elem.innerText="新内容";
以上两个属性,都是专门为双标签准备
3、*value - 有的单标签也是可以书写内容的,如何操作呢
获取:input.value;
设置:input.value="新内容";
2、获取、设置属性:
获取属性值:elem.getAttribute("属性名");
设置属性值:elem.setAttribute("属性名","属性值");
简化版操作:
获取属性值:elem.属性名;
设置属性值:elem.属性名="属性值";
2个小缺陷:
1、class必须写为className
2、只能操作标准属性,不能操作自定义属性
建议:开发中优先使用简化版,简化版实现不了的再用复杂版补充
3、样式:
操作样式的3种方式:
1、内联样式 - js操作就要他
优点:1、优先级最高 - 绝对能生效
2、不会牵一发动全身 - 只会修改当前元素
缺点:1、获取时,也只能获取到内联样式 - 可以忽略不计
2、内部样式表
3、外部样式表
获取样式:elem.style.css属性名;
设置样式:elem.style.css属性名="css属性值";
特殊:css属性名由横线的地方,去掉横线,换为小驼峰命名法
4、绑定事件:不要像以前一样,写在HTML上,不符合我们内容(HTML)与样式(CSS)与行为(JS)的分离
elem.onclick=function(){
操作;
//事件中有一个关键字:this(指针)
单个元素绑定事件:this指向就是这个元素
多个元素绑定事件:this指向就是当前触发事件的元素
}
强调:操作
一切的获取,都是为了判断,比较
一切的设置,都是为了修改