js概述
HTML+CSS+JavaScript并称前端三件套分别有着不同的功能,HTML负责的是网页的结构,css负责网页的样式,js负责网页的动态交互;
js分为ECMAScript - 核心语法,以后JS不管做什么操作可能都离不开它(算法题/逻辑题)
DOM - Document Object Model - 文档对象模型,可以用JS来操作HTML和CSS了
BOM - Browser Object Model - 浏览器对象模型,可以用来操作浏览器
一、js是一门弱类型、解释型、面向对象的脚本语言
1.弱类型:变量保存的数据是可以随意的,数据类型是由数据来决定的。----要求比较自由
强类型:变量保存的数据,是由数据类型来决定的。---要求比较严格
2.解释型:在运行程序之前,不需要先检查语法是否正则,直接执行,但是碰到错误就会停止后续代码。
编译型:在运行程序之前,需要先检查语法是否正则,如果不正确,直接不允许运行。
3.面向对象:编程中,万物皆对象。
二、js的两种使用方法
1.直接在HTML的script标签中写js代码。
2.通过script标签的src属性,外部引入js代码。(该script标签不能再写其他代码)
三、如何检查js代码
1.通常使用console.log()输出在控制台并分析代码的错误。
2.使使用document.write()输出在页面上查看并分析代码的错误。
3.在弹出框输出日志:alert()输出在BOM上的警告弹出框中查看输出的代码。
js基本数据
js数据类型:
-
值/基本数据类型:数字(Number)、字符串(String)、布尔类型(Boolean)、undefined、null、Symbol。 -
引用数据类型/对象类型:对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)
数据类型的转换
一、数据的隐式转换
算数运算符具有隐式转换功能
“+”运算
-
把“+”两边转换成数字类型进行运算。 -
碰见字符串“+”运算变成拼接操作。 -
碰见boolean类型 true>>>1,false>>>0。 碰见undefined>>>NaN。碰见null>>>0。
“*/%”运算
- 字符串也可以转为一个数字,前提要是一个纯数字组成的字符串才行,但凡包含一个非数字字符就转为NaN
- NaN:Not A Number:不是一个数字,但却是数字类型
-
NaN参与任何算术运算结果都是NaN -
NaN参与任何比较运算结果都是false(和自己比较也是false)
二、强制类型转换
-
转字符串:var str=x.toString();---x不能是undefined或null,因为undefined和null不能使用任何的.操作页面上的一切东西,数据类型默认都是一个字符串。 -
转数字:
-
parseInt(str/num); parse->解析 Int->整型 -
parseFloat(str); parse->解析 Float->浮点型 -
Number(x); (不好用)此方法可使任何类型转为数字,但是完全等效于隐式转化
function函数基础
-
Function:函数,称之为方法:需要提前【预定义好】的,以后就可以【反复使用】的【代码段】。 -
如何使用: 1、先定义/声明/创建函数: function 函数名(){ 若干的代码 } 2、再调用/使用函数: 1、要么在js中程序员直接写死,要执行几次:函数名(); 2、交给用户绑定在某个元素上,写上点击事件,让用户来触发。 <elem onclick="js代码">内容</elem> -
带参数的函数:创建:形参:形式参数,其实就是一个变量,但是不需要写var,而且默认也没有保存任何值,默认值为undefined function 函数名(形参,形参,...){ 函数体; } 使用:实参:实际参数,真正的值,需要再你调用时再传入 函数名(实参,实参,...) 特殊:1、传实参的顺序一定要和形参的顺序一一对应,并且数量也要对应 2、不是一定要带参数的函数才是好函数,具体情况,需要具体分析: 如果你的函数体就是固定的 - 则普通函数 如果你的函数体希望根据传入的实参不同,做的略微不同 - 则带有参数的函数
分支结构
-
程序的流程控制语句:3种 1、顺序执行 - 默认,从上向下的依次执行 2、分支结构 - 通过条件的判断,选择部分代码执行 3、循环结构 - 通过条件的判断,选择要不要重复执行某些代码 -
比较运算符:>、 <、 >=、 <=、 ==、 != 用于做判断/比较的 结果:一定是一个布尔值 强调:如果你想要判断多个条件,绝对不能像小时候数学的写法:18<=age<=65,错误的! 解决:逻辑运算符 -
逻辑运算符: &&:与,并且:要求全部条件都要满足,最后的结果才为true 只要有一个条件不满足,结果则为false ||:或:要求全部条件都要不满足,最后的结果才为false 只要有一个条件满足,结果则为true !:颠倒布尔值 -
分支的语法: 一个条件,一件事,满足就做,不满足就不做 if(条件){ 操作 } 一个条件,两件事,满足就做第一件,不满足就做第二件 if(条件){ 操作 }else{ 默认操作 } 多个条件,多件事,满足谁就做谁 if(条件1){ 操作1 }else if(条件2){ 操作2 }else{ 默认操作 }
循环结构
循环结构:反复执行【相同或相似】的操作
-
循环三要素: 1、循环条件:开始 - 结束,循环的次数 2、循环体:做的操作是什么 3、循环变量:记录着我们当前在哪一次,而且他会不断的变化,往往都会向着不满足循环条件进行 -
while循环: 语法: var 循环变量=几; while(循环条件){ 循环体; 循环变量变化; 特殊:有的时候真可能不知道从何开始,到何处结束, 死循环:永远不会停下来的循环 何时使用:不确定循环次数的时候 while(true){ 循环体; } 退出循环语句:break - 只能在循环中使用,多半都是搭配死循环使用的
数组的基础
数组:创建一个变量可以保存【多个数据】的集合
数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素
除了最后一个元素,每个元素都有唯一的后继元素
每个元素都有一个自己的位置,称之为叫做下标,下标是从0开始的,到最大长度-1
-
创建数组:2种 1、直接量方式: var arr=[];//空数组 var arr=[数据1,....]; 2、构造函数方式: var arr=new Array();//空数组 var arr=new Array(数据1,....);//而且这个方法还有一个坑 -
获取数组中的数据 数组名[下标]; -
添加/替换 数组名[下标]=新值; 下标处有没有元素,如果没有则为添加,如果有了就为替换 -
数组具有三大不限制 1、不限制元素的个数 2、不限制元素的类型 3、不限制元素的下标越界 - 会得到undefined,这是编程中不想看到的 如果获取元素,下标越界,返回的一个undefined 如果添加元素,下标越界,会得到一个稀疏数组,导致下标不再连续,如果搭配上循环去遍历每一个元素的话,我们会得到很多很多的undefined -
解决:数组中唯一的属性:长度:数组名.length - 获取当前数组的长度:最大下标+1 三个固定套路: 1、获取倒数第n个元素:arr[arr.length-n] 2、始终向末尾添加元素:arr[arr.length]=新值; 3、缩容:删除倒数n个元素:arr.length-=n 前面的下标好数,后面的下标也好数,但是中间的下标还是不好数 -
往往很多情况,我们不会拿出某个元素来使用,而是拿出所有的每个元素来进行 相同 或 相似的操作 遍历数组:把数组中的每个元素拿出来执行相同相似的操作 公式: for(var i=0;i<数组名.length;i++){ console.log(数组名[i]); }
DOM
-
Document Object Model:文档对象模型:专门用于操作HTML文档的,提供了一些属性和方法等待我们学习 -
DOM树概念:DOM将我们的HTML看做了是一个倒挂的树状结构,但是树根不是html标签,而是document对象 document对象:不需要我程序员创建的,由浏览器的js解释器自动创建,一个页面只有一个document 作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法) DOM会将页面上每个元素、属性、文本、注释都会当作一个DOM元素/节点/对象 -
查找元素: 一、通过ID查找元素 语法:var elem=document.getElementById("id值"); 特殊: 1、返回值,找到了返回的是一个当前找到的DOM元素,没找到,返回一个null,做了别的操作可能就会报错了 2、找到了多个相同的id,那么只会返回第一个 3、一次只能获取一个元素,也只能操作一个元素,麻烦 4、其实根本不需要使用此方法,直接写ID也可以找到元素 二、通过标签名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByTagName("标签名"); 特殊: 1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合 2、JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素 3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了 三、通过class名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByClassName("标签名"); 特殊: 1、返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合 2、JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素 3、不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了 四、通过关系查找元素:前提条件:必须先找到一个元素才可以调用关系网 父元素:elem.parentNode; 子元素:elem.children; - 集合 第一个儿子:elem.firstElementChild; 最后一个儿子:elem.lastElementChild; 前一个兄弟:elem.previousElementSibling; 后一个兄弟:elem.nextElementSibling; 强调:DOM集合不能直接做操作!
操作元素:
前提:找到元素才能操作元素:<标签 属性名="属性值" style="样式">内容</标签>
1、*内容:
1、*innerHTML:获取 和 设置 开始标签到结束标签之间的内容 - 支持识别标签
获取:elem.innerHTML;
设置:elem.innerHTML="新内容";
2、innerText:获取 和 设置 开始标签到结束标签之间的文本 - 不支持识别标签
获取:elem.innerText;
设置:elem.innerText="新文本";
以上两个属性都是为双标签准备的,但是操作不了单标签input的内容
3、*value:专门为input的value值准备的
获取:input.value;
设置:input.value="新值";
2、属性:
获取属性值:elem.getAttribute("属性名");
设置属性值:elem.setAttribute("属性名","属性值");
可简化为:
获取属性值:elem.属性名;
设置属性值:elem.属性名="新属性值";
缺陷:
1、class必须写为className - 2015年过后,ES6诞生过后,class变成了一个关键字
2、不能操作自定义属性,只能操作标准属性
3、样式
使用样式的方式:
1、*内联/行内样式
2、内部样式表
3、外部样式表
获取:elem.style.css属性名;
设置:elem.style.css属性名="css属性值";
特殊:
1、css属性名,有横线的地方,去掉横线,线后第一个字母大写
例:border-radius -> borderRadius
2、获取时,只能获取内联样式
4、绑定事件:
elem.on事件名=function(){
操作;
}
*****this关键字:目前只能用于事件内:
如果单个元素绑定事件:this->这个元素
如果多个元素绑定事件:this->当前触发事件的元素
5、eval()方法
*函数*功能 :eval()通常用来执行一个字符串表达式,并返回表达式的值。