变量和常量
1,变量:变量是一个可以修改,变化的值/数据
使用:当你需要反复使用一个数据/值,设置一个变量
语法:var 变量名=值/数据
建议:变量取名尽量见名知意: var name=“名字” 千万不要用关键字当作变量名
2,常量:常量是一个不能修改的值/数据
使用:和变量基本一样,基本不用。
语法:const 常量名=值/数据
打桩输出
1,在控制台日志输出:
consloe.log(想要输出的内容);
2,在页面输出:
document.wriet(想要输出的内容);
3,在警告框输出:
alert(想要输出的内容)
算术运算符
+ - * / % :前四个和数学运算时一样
%:取余/模 -> 两个数相除,不取商取余,取除不尽的那个余。
主要用于判断某个数字的奇偶性和取出某个数字的后n位1234%10=4 1234%100=34 ...
数据类型
1,String -> 字符串 取值有无数个,但必须写上""/''
2,Number -> 数字 取值有无数个,直接书写
3,Boolean -> 布尔 取值有两个,true(真,对)或false(假,错) 多用于判断的结果
4,Null -> 空 取值只有一个,null 用于释放内存/变量
5,undefined -> 垃圾 取值只有一个undefined 元素没有赋值时值为undefined
引用/对象类型:11个对象(每一个对象必有一个属性的方法)
隐式转换/显示转换
算术运算符具有隐式转换:算术运算符都是悄悄在我们程序员看不到的地方默认以数字计算
- * / % 也可以计算字符串,前提条件是这个字符串必须是纯数字。
但凡有一个非数字符号,结果都为NaN
特殊:+号 在遇到有字符串的运算时会把两边都变成拼接操作,最后的结果也还是一个字符串
不管是什么运算只要没有碰到字符串都会悄悄转为数字
true -> 1 false-> 0 null -> 0 undefined -> NaN
NaN:Not a Number -> 这不是一个数字,但确实是一个数字类型
纯粹的垃圾,参与任何算数运算都为NaN,参与任何比较运算都为false,它甚至不认识自己
所以我们没法用普通的方式去判断一个值是不是NaN
解决:!isNaN(x)此方法不管你放的X是什么都会悄悄转为一个数字
!isNaN(x)结果为false说明这是个一个NaN 结果为true说明这个一个有效数字
显式转换/强制转换:当隐式转换出的结果不是我们想要的,我们就用强制转换转换为数字在计算
转为字符串
toString(X) -> 转换为字符串,一般不用。因为一切从页面上获取的元素都是字符串
转为数字:一般用于字符串转为数字
pearInt(X) -> 转为一个整数,不认识小数点
执行原理:从左到右一个一个的识别数字,遇到非数字字符就停止
pearFloat(X) -> 转为一个小数,认识第一个小数点
执行原理:从左到右一个一个的识别数字,遇到除第一个小数点之外的非数字字符就停止
以上两个方式X必须是字符串,如果不是字符串则统一为不认识,结果就为NaN
Number(x) -> 万能转换,可以把任何类型转换为数字,但我们不用。
因为隐式转换的底层就是在使用这个转换,与其手动使用它不如用x*1 x/1 x-1 x%1
函数:function
函数:需要我们提前【预定好的】可以【反复使用】的一个【代码段】
1,创建:function 函数名(){代码段}
2,调用:函数名() 程序员写几次就调用几次
<标签名 onclick="函数名()"></标签名> 用户触发几次就调用几次
何时使用函数:
1.当你不希望一打开网页就立即执行的
2.当你需要用户自己来触发的
3.当你需要反复使用
4.它是一个独立的功能体
***.函数的地位很高,属于第一等公民。函数在使用后会自己释放内存/变量
带参数的函数
可以比作是一个榨汁机,会根据放入不同的食材而得到不同的结果
创建:function(形参1, ...){函数体}
形参:形式参数简称形参,就是一个变量名,只不过不需要写var这个关键字,每个参数用,隔开
调用: function(实参1, ...){函数体}
实参:实际参数简称实参,每一个实参要和形参一一对应,顺序和个数都要。
例子:创建:function(name,age,height){我的名字是"name"我的年龄是"age"我的身高是"height"}
调用:function(姓名,18,180cm)
得到的结果就是:我的名字是"姓名"我的年龄是"18"我的身高是"180cm"
普通函数用于反复做一个相同的操作,带参数的函数用于反复做一个相似的操作。
结构
顺序结构:默认的,代码从上到下依次执行。
分支结构:根据条件选择部分代码执行。
1,一个条件一件事,满足就做不满足就不做
if(条件){操作}
2,一个条件两件数,满足就做第一件不满足就做另一件
if(条件){操作}
else{操作}
3,多个条件多件事,满足谁就做谁
if(条件){操作}
else if(条件){操作}
else{操作}
循环结构:根据条件符不符合来考虑要不要再执行一次代码
寻环结构就是反复执行 相同 或 相似 的操作
循环三要素:
1.循环变量
2.循环条件
3.循环变量的变化
while循环
语法:var 循环变量=几
while(循环条件){
循环体
循环变量的变化}
执行原理:先判断循环条件是否为true,如果是true执行一次循环体和循环变量的变化,
再判断循环条件是否为true,如果是true再执行一次循环体和循环变量的变化...
直到循环条件判断为false则停止退出循环。
特殊:死循环->永远不会结束的循环,可能会卡死但有用。
往往不确定循环次数的时候使用死循环
语法:while(true){循环体}
需要搭配break来停止循环,必须在循环体内使用。
for循环
语法:for(循环变量;循环条件;变量的变化){循环体}
执行原理和while循环一样,但语法更简洁。
特殊:循环变量和变量的变化可以写多个。
死循环语法:for(;;){循环体}
总结:
while循环语法更繁琐,建议只在不确定次数的循环时使用
for循环语法更简洁,推荐在确定次数的循环使用->大多数时候
问题
循环和函数都是在 反复使用相同 或 相似的操作时使用的,那么它们有什么区别呢?
函数是程序员调用几次就执行几次或者用于触发几次就执行几次
而循环是程序员写好的,几乎在一瞬间就执行完毕了的
数组
数组:需要一个变量保存多个/所有的数据
数组里的元素是按照线性顺序排列,除了第一个元素每一个元素都有一个唯一的前驱元素,除了最后一个元素每一个元素都有一个唯一的后继元素,而每一个元素都有一个唯一的编号,称之为【下标】从0开始到最大长度-1结束。
创建数组:
var arr[元素,...] 或者 var arr=new Array(元素,...);
访问/获取数组:
arr[下标]
添加/覆盖:
arr[下标]="新元素" -> 下标没有元素则为添加,否则为覆盖
特点:数组的三大不限制:
1.不限制元素类型;
2.不限制元素的数量;
3.不限制下标越界(这算是一个缺点)
获取时下标越界返回的为undefined,覆盖时下标越界会多出很多空元素稀疏数组,导致下标不连续。
数组有一个唯一的属性:arr.length;获取数组的长度
三个固定套路:
向末尾添加元素arr[arr.length]=新元素
获取倒数第n个元素arr[arr.length-n]
删除倒数n个元素arr.length-=n
注意:我们通常不会单独拿出数组中的一个元素来操作,往往是拿出所有的元素来操作
所以我们这个时候要用到遍历数组:将元素中的每一个元素拿出来做相同 或 相似的操作
语法:for(i=0;i<arr.length;i++){arr[i]}
JavaScript三大组成部分
1.ECMAScript(3/5/6)->核心语法,像是在做应用题
2.DOM -> Document Object Model -> 文档对象模型 -> 操作HTML文档
3.BOM -> Browser Object Model -> 浏览器对象模型 -> 操作浏览器
DOM概述:DOM树
dom将HTML看作是一个倒挂的树状结构;树根是一个叫做document的对象
document对象:不需要我们创建,一个页面自带一个document对象,由浏览器自行创建
作用:只要是对象就一定有(属性和方法)它提供我们可以找到并操作元素
查找元素:
get:找到 element:元素 by:通过
通过id查找:var elem=document.getElementById("id名")
返回的是一个dom元素,可以直接操作
通过class查找:var elem=document.getElementByTagName("class名")
通过标签查找:var elem=document.getElementByName("标签名")
返回的是一个dom集合,不可以直接操作
可以把document换成一个你已经找到了的父元素
通过关系获取元素:前提是必须先找到一个元素
找到父元素:elem.parentNode
找到子元素:elem.children ps:找到的是一个集合,不能直接操作
找到第一个儿子元素:elem.firseElementChild
找到最后一个儿子元素:elem.lastElementChild
找到上一个兄弟元素:elem.previousElementSibling
找到下一个兄弟元素:elem.nextElementSibling
操作元素
操作内容
innerHTML:获取或者设置元素的内容部分,并且能够识别标签
获取:elem.innerHTML;
设置:elem.innerHTML="新内容";
innerText:获取或者设置元素的文本部分,不能够识别标签
获取:elem.innerText;
设置:elem.innerText="新文本";
以上两个标签针对的是双标签
value:获取或者设置input的内容
获取:input.value
设置:input.value="新闻本";
操作HTML属性
getAttribute:获取或者设置元素的HTML属性部分
获取:elem.getAttribute("属性名")
简写:elem.属性名
设置:elem.getAttribute("属性名","属性值")
简写:elem.属性名="新属性值"
简写虽然简单方便,但是有缺点
1.class属性需要写作className
2.只能操作标准属性,不能操作自定义属性
所以建议:优先使用简写操作,简写满足不了的再用完整版操作
操作css样式
获取:elem.style.css属性名
设置:elem.style.css属性名="css新属性值"
特殊:设置css属性名如果有横线-,要去掉横线并使用小驼峰命名法。
获取只能获取内联样式里的属性 -> 忍一忍就过去了,解决方式很繁琐
在二阶段我们更喜欢使用内联样式,因为内联样式权重更高可以保证我们的样式必然生效
而且只会操作当前元素,不会牵一发而动全身。
获取:往往适用于判断
设置:其实就是修改
绑定事件
单个元素:单个元素:
elem.onclick=function(){
this->就是绑定事件的这个元素}
多个元素:多个元素:
for(var i=0;i<elems.length;i++){
elems[i].onclick=function(){
this->是当前触发事件的元素}}