第一周总结
day1
JavaScript
概述:
简称JS,是一个运行在js解释器中的一个【解释型】【弱类型】【面向对象】脚本语言
特点:
1.可以用任何编辑器编辑代码
2.解释型
3.弱类型
4.面向对象 特点解释
js解释器:
1.浏览器自带js解释器
2.以后会自己安装一个解释器-Node.js
解释型:
在运行程序之前,不需要检查程序是否报错,直接运行,碰到错误了才会停止
弱类型:
变量想保存什么数据类型就保存什么数据类型,由数据决定了数据类型是什么,比如JavaScript、php - 自由
引入方式
a. 在HTML中书写一个script标签 - 仅用于临时测试
b. 创建一个xx.js文件,再在HTML进行引入 – 用于正式开发中 建议: js放在我们的HTML和CSS的后面,最好是最后
找错方式:
打桩输出/疯狂打桩: 非常重要的一种找错方式: 3种;
a. 在控制台输出日志: console.log(想要输出的内容);
b. 在页面上输出: document.write(想要输出的内容); - 可以识别标签 缺点: 如果有点击事件触发document.write会导致页面原来的HTML全被覆盖掉,那你写的网页白写了
c. 用警告框输出: alert(想要输出的内容); 缺点: 会卡主页面,只能看到白板
day2
数据类型的转换
【一切的页面上获取来的数据类型都是字符串】
*隐式转换:
默认都是转为数字,在运算
如果精通了隐式转换,我根本不需要console.log我也知道最后的结果是什么
特殊:
1.不管是什么运算,只要没碰上字符串,都会悄悄的转为一个数字
true-->1
false-->0
undefined-->NaN
null-->0
2. +运算并且碰上字符串,则为拼接,最后的结果也就还是一个字符串
3. - * / %,就算是字符串也可以转为数字,前提是纯数字组成的字符串,但是如果包含了一个非数字字符,则为NaN "1000" -> 1000 "100a0" -> NaN
NaN:
Not a Number:
不是一个数字,但是确实是数字类型,只不过不在三界之内
缺点
1、不在三界之内,不大于,不小于,不等于,任何值,包括自己
2、参与任何算数运算+-*/%,结果仍为NaN
问题
正是因为NaN参与任何比较运算结果都为false,甚至自己都不认识自己,所以我们没有办法用一个普通的比较运算来判断x是不是NaN
解决
!isNaN(x): 此方法不管你放的x是什么都会悄悄的隐式转换为数字
true->说明是一个有效数字
false->说明是一个NaN
目的
防止用户恶意输入,但是目前为止,只能防止用户输入的必须是一个数字(比如验证的话我们做不了:正则学了才能做)
显式转换/强制转换:
隐式转换出来的结果不是我们想要的,先强制转换为需要的数据,再运算
使用:
1.转为字符串:
var str=xx.toString();//xx
不能是undefined和null,undefined和null不能使用点操作
因为一切的页面上获取来的数据类型都是字符串*2. 转为数字: 3种方式
parseInt(x); parse解析 Int整型:解析为一个整数
原理: 从左向右,依次读取每个字符,碰到非数字字符就停止,不认识小数点,如果一来就不认识则为NaN
作用: 去掉单位parseFloat(x); parse解析 Float浮点数:解析为一个小数
原理: 几乎和parseInt一致,但是认识第一小数点
作用: 去掉单位Ps: 以上两个方法很重要,但是x只能是数字或者字符串,不能是别的,如果是别的统一的认为是不认识的,不认识的结果就为NaN了
个人感觉,这两个方法是专门用于str to numNumber(x); -万能的,任何人都可以转为数字
垃圾:此方法完全等效于隐式转换 其实隐式转换的底层,就是悄悄地使用了此方法,所以我们绝对不会手动使用 还不如 x-0 /1 *1 %1
函数
也称之为方法:需要【预定义好】的,可以【反复使用】的一个【代码段】
js中的函数 - 完成了一个……的功能
创建函数:
function 函数名(){
代码段;//若干操作
}
调用函数:
1.直接在js中程序员写几次调用,就会执行几次操作:
函数名();
2.让用户来自己触发:
<elem onclick="函数名()"></elem>
何时使用函数:
1.函数的js地位很高,属于第一等公民地位
2.你不希望打开页面立刻执行
3.能够反复执行
4.他是个独立的功能体
5.你不是自己释放内存,函数调用完毕会自动释放内存/变量
带有参数的函数:
1.创建带参数的函数:
function 函数名(形参,...){ 函数体; }形参:就是一个变量名,只不过这里的变量名不需要var,并没有保存真正的值,形式参数,简称形参
2.调用带参数的函数:
函数名(实参,...);
实参:实际参数,这个变量名所保存的值
一个函数可以执行相似的操作
比如:实现任意两个数相加:function add(a,b){ console.log(a+b); } add(1,2); add(3,4); add(5,6);注意:带参数的函数,在调用时,传入的实参的顺序和个数都要一一的和形参对应上
总结:
1.如果你的函数体是固定不变的,则不需要使用带参数的函数
2.如果你的函数体希望根据传入的实参的不同,做的事儿也略微不同,需要使用带参数的函数
分支结构
代码中流程控制语句
1.顺序结构:
默认结构,代码从上向下一步一步执行的
2.分支/选择结构:
根据条件,选择一部分代码去执行
3.循环结构:
根据条件,判断你是否需要再一次重复的执行某一些代码
if结构
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
day3
循环结构
什么是循环:
反复执行 【相同 或 相似】 的操作,几乎是一瞬间就完成了很多次
循环三要素:
1.循环条件:开始、结束,重复执行的次数
2.循环体:循环操作,干什么事
3.循环变量:创建,并且要让他不断的改变(自增、自减),往往向着不满足循环条件在变化
while循环:
语法:
`var 循环变量=几; `
`while(循环条件){
循环体;
循环变量的变化;
}
原理:
先判断循环条件,如果条件为真,则执行一次循环体中的语句,然后再一次判断循环条件,如果为真,则再执行一次循环体中的语句…直到循环条件为假,才会退出循环
强调:
循环是一次一次执行的,只不过速度很快,而且循环没结束之前,会卡主后续代码
死循环:
停不下来的循环,多半用于不确定循环次数的时候
while(true){
循环体;
}
循环流程控制语句:
死循环多半都要搭配上一个退出循环:break; - 可以出现在任何一个循环之中
for循环:
和while能做的事是一模一样的,只不过语法比while更简单,看上去也更加的舒服
语法:
for(var 循环变量=几;循环条件;循环变量的变化){
循环体;
}
特殊:
1.死循环:
for(;;){循环体}
2.创建循环变量部分,也可以,隔开创建多个变量
数组
数组中的元素,都是按照线性顺序排列
特点:
除了第一个元素,每个元素都有一个唯一的前驱元素
除了最后一个元素,每个元素都有一个唯一的后继元素
*数组中的每个元素都有一个唯一的位置序号,称之为【下标】,用来表示数组中的每一个元素,下标是从0开始的,到最大长度-1结束
创建数组:
1. 直接量方式:
var arr=[];//空数组
var arr=[元素,元素,...];
2.构造函数方式:
var arr=new Array();//空数组
var arr=new Array(元素,元素,...);
访问数组中的元素
数组名[下标];
添加/修改数组中元素:
数组名[下标]=新元素;
特殊:
1.下标处如果没人,则为添加
2.下标处如果有人,则为替换
3.如果下标越界 - 会导致我们的数组变为一个稀疏数组,不是好东西,因为会导致下标不在连续
数组具有3大不限制:
1、不限制长度
2、不限制类型
3、不限制下标越界: 获取时,下标越界,返回结果是一个undefined
添加时,下标越界,导致我们的数组变为一个稀疏数组,不是好东西,因为会导致下标不在连续
数组是一个长度无限的公交车,没坐人的地方其实也有一个默认值为undefined
数组有一个唯一的属性:
获取到数组的长度
数组名.length;
三个固定套路:
1.向末尾添加元素:
arr[arr.length]=新元素;
2.获取倒数第n个元素:arr[arr.length-n];
3.缩容:删除末尾n个元素:arr.length-=n;
遍历数组:
把数组中的每一个元素都取出来执行相同 或 相似的操作
公式:
for(var i=0;i<数组名.length;i++){
数组名[i];
}
day4
查找元素
通过HTML的特点去查找元素:
id查找:var elem=document.getElementById("id值");
在当前DOM树中,根据元素的id,获取具体的DOM节点
返回: 找到了,返回对应的元素
没找到,null
特殊:
1.如果页面上有多个重复的id,只会返回第一个
2.此方法找到的是单个元素 - DOM节点是可直接用于做操作的
3.此方法你不能使用 - 以后留给后端工程师使用
标签名查找:
var elems=document/已经找到的父元素.getElementsByTagName("标签名");
在当前DOM树中,根据标签名获取元素们
返回:找到了,返回一个DOM集合
没找到,空数组
特殊:
1.返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部
2.不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素
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、type、href...只要是放在HTML标签上的都是一个属性
1.获取属性值:elem.getAttribute("属性名");
2.设置属性值:elem.setAttribute("属性名","属性值");
以上两个方法有点繁琐 - 但是无敌的
简化:
1.获取:elem.属性名;
2.设置:elem.属性名="属性值";
缺陷:
- 不能操作自定义属性,只能操作标准属性
- class在ES6升级为了一个关键字,所以想要写class换为了className
样式:
css定义的方式:
1.内联样式 - 二阶段
2.内部样式表
3.外部样式表 - 最适合写样式的时候使用此方法
JS操作内联样式的好处:
1.优先级最高,写的JS样式必定生效
2.一次只会操作一个元素,不会牵一发动全身
语法:
获取:
elem.style.css属性名;
设置:elem.style.css属性名="css属性值";
特殊:
1.css属性名,要把有横线地方去掉,换成小驼峰命名法
2.获取的时候,只能获取内联样式,不能获取样式表中的样式
元素绑定事件:
单个元素:
elem.onclick=function(){
操作;
this->单个元素绑定事件,绑定事件的这个元素
}
多个元素:
for(var i=0;i<elems.length;i++){
elems[i].onclick=function(){
操作
this->多个元素绑定事件,当前触发事件的元素
}
}
总结:
1.一切的获取都是为了判断
2.一切的设置都是为了修改
3.千万不要对着一个集合做操作,要么遍历拿全部,要么下标拿一个