JavaScript入门学习第一周
JavaScript的基本概念
JavaScript概述
JavaScript是在解释器中或特定引擎中运行的一种解释性、弱类型、面向对象型的脚本语言。
- 解释型:在运行程序之前不需要检查语法是否正确,直接运行,碰到错误后停止运行;
- 弱类型:变量不需要进行规定,想放什么放什么,变量的数据类型由变量的值决定;
- 面向对象型:一切的东西都有自己的属性
对象.属性和方法对象.方法名()。
JavaScript的作用
- 客户端的数据计算;
- 表单的数据运算;
- 提供事件;
- 网页中用CSS做不了的特效;
- 和服务器进行交互(ajax)。
JavaScript的使用
- html中
<script>代码</script>; - 创立一个xx.js文件
<script src="xx.js文件的路径">不能再写代码(无效)</script>。
JavaScript的调试语句
代码再运行期间,如果遇到错误会立即报错,且后续代码不会继续执行;但若只是逻辑错误不是语法错误,就不会报错且后续代码不会继续执行,那就需要一个方法帮助我们把找到错误所在位置。
- 在控制台输出日志:
console.log(输出);打桩输出,疯狂打桩,找到错误所在; - 在页面输出:
document.write(输出);缺点:绑定事件后会替换页面所有内容; - 警示框显示:
alert(输出);缺点:会卡住整个页面,必须关闭才能看到页面内容。
JavaScript的语法规范
严格区分大小写,不能乱写:如console.log();√ console.Log();×
JavaScript的注释
- 作用:1、提示程序猿;2、玩。
- 单行注释://或Ctrl+/;
- 多行注释:/* */ 或Shift+Alt+A
变量
变量的定义
变量的值是可以改变的,只要以后需要用到的数据都可以保存在变量中,以后使用变量名就相当于使用这个变量了。
变量的语法
var 变量名=值;
变量的特殊
- =是赋值符号,将=右边的数据赋值给左边的变量名之中;
- 若只声明/定义/创建变量,没有赋值的话,默认为undefined(初始值);
- 取变量名尽量见名知意,且不能以数字开头;
- 若创建多个变量,中间的var可以省略且中间的 ; 换为 ,号,但是最后依然是;结束;
- 若一个未声明的变量直接使用会报错;
- name变量名是一个关键字,里面放得值均会变成字符串。
算术运算符
算术运算符包含:+ - * / %;
%
取余也叫模,两数相除,取余数。例如5%2==1,2%5==2;
%的作用
- 判断奇偶性,num%2==0;为偶数;num%2==1;为奇数;
- 获取某个数字的最后n位:1234%10==4;1234%100==34;
隐式转换
隐式转换含义
数据类型会发生变化,我们看不见,常理来说只有数字能进行算术运算,默认运算符左右两边都会转换为数字再进行运算。
隐式转换特殊
- +运算,只要碰上一个字符串则两边都转换成字符串,+运算也变成了拼接字符串;
-
-
- / % 运算,纯数字的字符串可以转化为数字,只要有非数字字符,结果都为NaN;
-
- NaN不是一个数字,但是是一个数字类型;
- NaN与任何数进行算术运算,结果都为NaN;
- NaN参与比较运算结果都为false。
JavaScript的数据类型
原始/基本/值类型
- String-字符串:取值有无数个,必须带"";
- Number-数字:取值有无数个,直接写数字;
- Boolean-布尔值:取值true或false,用于判断;
- Undefined-取值undefined,没有用;
- Null-空:取值null,作用:释放内存、变量,节约空间;
分支结构
- 多个条件多件事,满足谁就做谁
if(条件1){
操作1
}else if(条件2){
操作2
}else if(条件3){
操作3
}else{
默认操作;
}
- 注意:
- else if你想写几句就写几句;
- 最后的else其实也可以省略,但是如果条件都不满足的话则什么不会执行;
- 分支结构只要满足一个就不可能再走另一条路了。
小练习
<button onclick="hambur()">请输入你想吃的套餐</button>
<script>
function hambur(){
var hamburger=prompt("请输入您想吃的汉堡"),pc=prompt("请输入您想吃的配餐"), drinks=prompt("请输入您想喝的饮料");
alert(hamburger+"套餐:"+hamburger+"+"+pc+"+"+drinks)
}
</script>
<button onclick="kltt()">计算可莱托指数</button>
<script>
function kltt(){
var height=prompt("请输入您的身高(M)"),weight=prompt("请输入您的体重(KG)");
if (!isNaN(height)&&!isNaN(weight)){
var klt=weight/(height*height);
if (klt>25){
alert("胖了");
}else if(klt<20){
alert("瘦了");
}else{
alert("正常");
}
}else{
alert("恶意输入");kltt();
}
}
</script>
数据类型的转换
- javascript是弱类型语言,数据类型都是由数据来决定的
- 对于不同数据类型的运算时,数据类型会进行转换:
- number + number = number;
- number + string = string;
- 如果你喜欢查看数据类型:typeof(需要检查的人)。
算术运算的隐式转换(其他运算也有)
特殊
- true->1;
- false->0;
- undefined->NaN;
- null->0.
解决判断是否为NaN
!isNaN(x);结果为true:是有效数字;结果为false:是一个NaN;
强制/显式转换
隐式转换的结果可能不是我们想要的,我们可以手动调用某些方法,进行数据类型的转换后,再运算。
转为字符串
语法:var str=x.toString();->x不能是undefined和null,因为undefined和null不能操作。
转数字:3个方法
var num=parseInt(str/num);parse->解析 Int->整型/整数
- 原理:从左向右依次读取每个字符,进行转换,碰到非数字字符就停止,而且不认识小数点,如果一开始就碰到了不认识的字符,结果为NaN
console.log(parseInt("35.5"));->35;;console.log(parseInt(布尔、undefined、null));->NaN。
var num=parseFloat(str/num);parse->解析 Float->浮点数/小数
- 原理:从左向右依次读取每个字符,进行转换,碰到非数字字符就停止,认识小数点,如果一开始就碰到了不认识的字符,结果为NaN
console.log(parseFloat("35.5"));->35;console.log(parseFloat(布尔、undefined、null));->NaN。
Number(x);->x是万能的,完全是隐式转换,无用。
总结
- 只要页面上带有单位的数字,我们都可以用parseXXX来去掉单位变为数字;
- Number何时都不用。
函数
函数的概念
也称为方法,需要预定义/提前创建好后,可以反复使用的代码段(里面可以放若干代码)。
创建并调用函数
创建
function 函数名(){ 若干代码段 }
调用
- 直接在js里面写 函数名(); 写几次就会执行几次;
- 绑定在页面的元素上,让用户来触发,用户触发一次就会执行一次 - 提升用户体验感/多了交互感
<elem onclick="函数名();"></elem>。
何时要使用函数
- 打开页面不希望立刻执行;
- 希望用户/程序员来触发;
- 希望能够被反复执行;
- 本身就是一段独立的功能体:暂时理解为我们的每一个作业就是一个独立的功能体;
- 尽量的将每个功能封装为一个函数,函数是第一等公民的地位,而且函数中的变量会自动释放。
带有参数的函数
创建带有参数的函数
- 形参:就是一个变量名,只不过这里的变量名不需要var,并没有保存真正的值,形式参数,简称形参。
function 函数名(形参,...){ 函数体; }
调用带有参数的函数
- 实参:实际参数,这个变量名所保存的值函数名(实参,...)
- 一个函数可以执行相似的操作
- 比如:实现任意两个数相加:
function add(a,b){
console.log(a+b);
}
add(1,2);
- 注意:带参数的函数,在调用时,传入的实参的顺序和个数都要一一的和形参对应上。
总结
- 如果你的函数体是固定不变的,则不需要使用带参数的函数;
- 如果你的函数体希望根据传入的实参的不同,做的事儿也略微不同,需要使用带参数的函数。
分支结构
代码中流程控制语句
- 顺序结构: 默认结构,代码从上向下一步一步执行的;
- 分支/选择结构:根据条件,选择一部分代码去执行;
- 循环结构:根据条件,判断你是否需要再一次重复的执行某一些代码。
比较运算符
- 作用:比较判断/条件中出现;
- 结果:以上六个运算符,结果一定是一个布尔值;
- 比较运算符也具有隐式转换,但是我不给你说,大部分情况下依然会转为数字在比较大小。
if结构
if(条件1){
操作1
}else if(条件2){
操作2
}else if(条件3){
操作3
}else{
默认操作;
}
逻辑运算符
- &&:只有全部条件都满足,最后结果才为true只要有一个条件为false,结果就为false;
- ||:只有全部条件都不满足,最后结果才为false只要有一个条件为true,结果就为true;
- !:颠倒布尔值!true -> false !!!true -> false。
小练习
<button onclick="multiply()">3个数乘积计算</button>
<script>
function multiply(a,b,c){
var a=parseFloat(prompt("请输入第一个数字")) , b=parseFloat( prompt("请输入第二个数字")),c=parseFloat( prompt("请输入第三个数字"));
if(!isNaN(a)&&!isNaN(b)&&!isNaN(b)){
alert(a*b*c);
}else{
alert("皮一下很开心?");multiply()
}
}
</script>
<button onclick="revenue()">自动计算税收</button>
<script>
function revenue(){
var salary=Number(prompt("请输入您的工资"));
if(!isNaN(salary)){
var add=0;
if(salary>=9000){
// var a=((salary-9000)*0.1+4000*0.05+1500*0.025);
// alert("您需要缴纳的税收为:"+a+"元");
add+=(salary-9000)*0.1
salary=9000;
} if(salary>=5000){
// var a=((salary-5000)*0.05+1500*0.025);
// alert("您需要缴纳的税收为:"+a+"元");
add+=(salary-5000)*0.05
salary=5000;
} if(salary>3500){
// var a=((salary-3500)*0.025);
add+=(salary-3500)*0.025
alert("您需要缴纳的税收为:"+add+"元");
// salary=9000;
} if(salary<=3500){
alert("你个穷逼,连税都交不了!")
}
}else{
alert("喜欢玩?那就再来亿次!");revenue();
}
}
</script>
循环结构
循环:反复执行相同或相似的操作,几乎是一瞬间就完成了很多次。
循环三要素
- 循环条件:开始、结束,重复执行的次数;
- 循环体:循环操作,干什么事;
- 循环变量:创建,并且要让他不断的改变(自增、自减),往往向着不满足循环条件在变化。
while循环
语法
var 循环变量=几;
while(循环条件){
循环体;
循环变量的变化;
}
原理
先判断循环条件,如果条件为真,则执行一次循环体中的语句,然后再一次判断循环条件,如果为真,则再执行一次循环体中的语句...直到循环条件为假,才会退出循环。
强调
循环是一次一次执行的,只不过速度很快,而且循环没结束之前,会卡主后续代码。
死循环
-
停不下来的循环,多半用于不确定循环次数的时候 while(true){ 循环体; }
-
循环流程控制语句:死循环多半都要搭配上一个:退出循环:break; 可以出现在任何一个循环之中。
for循环
语法
for(var 循环变量=x;循环条件;循环变量的变化){
循环体;
}
原理
先判断循环条件,如果条件为真,则执行一次循环体中的语句,然后再一次判断循环条件,如果为真,则再执行一次循环体中的语句...直到循环条件为假,才会退出循环。
强调
循环是一次一次执行的,只不过速度很快,而且循环没结束之前,会卡主后续代码。
死循环
- 停不下来的循环,多半用于确定循环次数的时候。
for(;;){循环体} - 循环流程控制语句:死循环多半都要搭配上一个:退出循环:break; 可以出现在任何一个循环之中。
总结
- while循环:一般用于 循环次数不明确的情况,死循环;
- for循环:一般用于 已经确定了循环次数的情况,语法更加的简便。
数组
创建数组
- 直接量方式:
var arr=[];->空数组var arr=[元素,元素,...]; - 构造函数方式:
var arr=new Array();->空数组var arr=new Array(元素,元素,...);
访问数组中的元素
数组名[下标];
添加/修改数组中元素
数组名[下标]=新元素;
特殊
- 下标处如果没人,则为添加;
- 下标处如果有人,则为替换;
- 如果下标越界,会导致我们的数组变为一个稀疏数组,因为会导致下标不在连续。
数组具有3大不限制
- 不限制长度 - 优点;
- 不限制类型 - 优点;
- 不限制下标越界。
- 获取时,下标越界,返回结果是一个undefined;
- 添加时,下标越界,因为会使得下标不再连续,导致我们的数组变为一个稀疏数组。
数组唯一的一个属性
语法
数组名.length;
有了这个属性,我们就可以实现数组的三个固定套路:
- 永远希望想末尾添加元素:
arr[arr.length]=新值;; - 获取倒数第n个:
arr[arr.length-n];; - 缩容:删除数组的倒数n个:
arr.length-=n。
遍历数组
- 把数组中的每一个元素都取出来执行相同或相似的操作。
for(var i=0;i<数组名.length;i++){
数组名[i];//当前次拿到的数据
}
小练习
<!-- 99乘法表 -->
<script>
for(var j=1;j<10;j++){
for(var i=1,str="";i<=j;i++){
str+=i+"*"+j+"="+i*j+" ";
} console.log(str);
}
</script>
<!-- 查找指定元素 -->
<button onclick="zhao()">找是第几个</button>
<script>
function zhao(){
var arr=["万","事","开","头","难","中","间","南"],index=-1;
var users=prompt("请输入"+arr);
for(var i=0;i<arr.length;i++){
if(users==arr[i]){
index=i;
// console.log(index);
}
}
if(index!=-1){
console.log("找到了,他是第"+index+"个")
}else{
console.log("没找到")
}
}
</script>
JavaScript的组成
- ECMAScript - 简称ES3/5/6,核心语法 - 内功心法(逻辑部分);
- Document Object Model - 简称DOM,文档对象模型 - 外功招式(专门用于操作网页文档HTML+CSS的);
- Browser Object Model - 简称BOM,浏览器对象模型 - 外功招式(专门用于操作浏览器的)。
DOM树
- DOM将HTML看做了是一个倒挂的树状结构。
- 树根:是一个document对象,document对象不需要我们程序员创建,由浏览器的JS解释器创建,一个页面只有一个document;
- 作用:提供了一些属性和方法,可以让我们程序员去操作整个DOM树(增删改查每一个DOM节点);
- DOM节点:一个标签、文本、属性、元素。
查找元素
通过HTML的特点去查找元素
- id查找:
var elem=document.getElementById("id值"); - 在当前DOM树中,根据元素的id,获取具体的DOM节点;
- 返回:找到了,返回对应的元素,没找到,null。
特殊
- 如果页面上有多个重复的id,只会返回第一个;
- 此方法找到的是单个元素 - DOM节点是可直接用于做操作的;
- 此方法不能使用 - 以后留给后端使用。
通过标签名查找元素
var elems=document/已经找到的父元素.getElementsByTagName("标签名");;
- 在当前DOM树中,根据标签名获取元素们;
- 返回:找到了,返回一个DOM集合,没找到,空数组。
特殊
- 返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部;
- 不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素。
通过标签名查找元素
var elems=document/已经找到的父元素.getElementsByClassName("标签名");;
- 在当前DOM树中,根据标签名获取元素们;
- 返回:找到了,返回一个DOM集合,没找到,空数组。
特殊
- 返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部;
- 不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素。
节点之间的关系进行查找
- 前提:必须先要找到一个人,才能使用关系。
- 父:elem.parentNode;->单个元素;
- 子:elem.children;->集合;
- 第一个儿子:elem.firstElementChild;->单个元素;
- 最后一个儿子:elem.lastElementChild;->单个元素;
- 前一个兄弟:elem.previousElementSibling;->单个元素;
- 后一个兄弟:elem.nextElementSibling;->单个元素。
操作元素
<标签名 属性名="属性值" style="样式">内容</标签名>
内容
- innerHTML属性:获取 或 设置 某个元素的内容,并且可以识别标签 ;
- 获取内容:elem.innerHTML;
- 设置内容:elem.innerHTML="新内容"。
- innerText属性:获取 或 设置 某个元素的文本,不能可以识别标签;
- 获取内容:elem.innerText;
- 设置内容:elem.innerText="新内容";
- 以上两个属性,是为双标签准备的。
- value属性:专门为单标签(input)操作内容准备的。
- 获取内容:input.value;
- 设置内容:input.value="新内容"。
属性
属性:HTML属性:id、class、title、alt、style、type、href...只要是放在HTML标签上的都是一个属性。
- 获取属性值:elem.getAttribute("属性名");
- 设置属性值:elem.setAttribute("属性名","属性值")。 能够简化
- 获取:elem.属性名;
- 设置:elem.属性名="属性值"; 简化的缺陷:
- 不能操作自定义属性,只能操作标准属性;
- class在ES6升级为了一个关键字,所以想要写class换为了className。
样式
css定义的方式
- 内联样式;
- 内部样式表;
- 外部样式表 - 最适合写样式的时候使用此方法。
JS操作内联样式的好处
- 优先级最高,写的JS样式必定生效;
- 一次只会操作一个元素,不会牵一发动全身。
语法
获取:elem.style.css属性名;;
设置:elem.style.css属性名="css属性值";;
特殊
- css属性名,要把有横线地方,换成小驼峰命名法;
- 获取的时候,代老湿只交了大家获取内联样式,不能获取样式表中的样式。
元素绑定事件
单个元素:
elem.onclick=function(){
操作;
this->单个元素绑定事件,this->elem绑定事件的这个元素;
}
多个元素
for(var i=0;i<elems.length;i++){
elems[i].onclick=function(){
操作;
this->多个元素绑定事件,this->当前触发事件的元素;
}
}
小练习
<!-- 选项卡-->
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
body {
display: flex;
}
li {
width: 150px;
background: pink;
line-height: 50px;
text-align: center;
color: #fff;
border: 1px solid #ccc;
cursor: pointer;
}
div {
width: 500px;
line-height: 32px;
text-indent: 2em;
background: purple;
color: #fff;
border: 1px solid #ccc;
display: none;
}
li.active {
background: purple;
}
div.active {
display: block;
}
</style>
<!-- body部分-->
<ul>
<li class="active" hc="0">十五元套餐</li>
<li hc="1">二十元套餐</li>
<li hc="2">三十元套餐</li>
</ul>
<div class="active">十五元套餐:Lorem ipsum, dolor sit amet consectetur adipisicing elit. Exercitationem ipsa pariatur, in
optio quia ipsum molestiae assumenda quasi, iste quas, vero veritatis dolorum explicabo voluptate maxime.
Deleniti dolores amet voluptatem?</div>
<div>二十元套餐:Lorem ipsum, dolor sit amet consectetur adipisicing elit. Exercitationem ipsa pariatur, in optio quia
ipsum molestiae assumenda quasi, iste quas, vero veritatis dolorum explicabo voluptate maxime. Deleniti dolores
amet voluptatem?</div>
<div>三十元套餐:Lorem ipsum, dolor sit amet consectetur adipisicing elit. Exercitationem ipsa pariatur, in optio quia
ipsum molestiae assumenda quasi, iste quas, vero veritatis dolorum explicabo voluptate maxime. Deleniti dolores
amet voluptatem?</div>
<script>
var lis = document.getElementsByTagName("li");
var divs = document.getElementsByTagName("div");
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
divs[i].className = "";
}
this.className = "active";
var j = this.getAttribute("hc");
divs[j].className = "active";
}
}
</script>
<!-- 购物车 -->
<table id="tbl">
<thead></thead>
<tbody>
<tr>
<td>iphone6</td>
<td>4488</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>4488</td>
</tr>
<tr>
<td>iphone7</td>
<td>5488</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>5488</td>
</tr>
<tr>
<td>iphone8</td>
<td>6488</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>6488</td>
</tr>
<tr>
<td>RTX 3090</td>
<td>20000</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>20000</td>
</tr>
<tr>
<td>RTX 3080</td>
<td>16000</td>
<td>
<button>-</button>
<span>1</span>
<button>+</button>
</td>
<td>16000</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">总计:</td>
<td id="total">0</td>
</tr>
</tfoot>
</table>
<script text="text/javascript">
var btn = document.getElementsByTagName("button");
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
if (this.innerHTML == "-") {
var span = this.nextElementSibling;
if (span.innerHTML > 1) {
span.innerHTML = parseInt(span.innerHTML) - 1;
}
var price = this.parentNode.previousElementSibling.innerHTML;
this.parentNode.nextElementSibling.innerHTML = price * span.innerHTML;
} else {
var span = this.previousElementSibling
span.innerHTML = parseInt(span.innerHTML) + 1;
var price = this.parentNode.previousElementSibling.innerHTML;
this.parentNode.nextElementSibling.innerHTML = price * span.innerHTML;
}
var total = document.getElementById("total"), body = document.getElementsByTagName("tbody")[0];
var trs = body.children;
for (i = 0, mon = 0; i < trs.length; i++) {
mon += (parseFloat(trs[i].lastElementChild.innerHTML));
} total.innerHTML = mon;
}
} var total = document.getElementById("total"), body = document.getElementsByTagName("tbody")[0];
var trs = body.children;
for (i = 0, mon = 0; i < trs.length; i++) {
mon += (parseFloat(trs[i].lastElementChild.innerHTML));
} total.innerHTML = mon;
</script>