一 JS 组成及写法
(一)前置知识
-
简述硬件 & 操作系统 & 软件(应用系统)之间的关系。
- 计算机是由多个硬件组成,例如:CPU、硬盘、内存、网卡、主板等。
- 操作系统则是安装在计算机上用于协调各硬件进行配合工作的,他将用户的一些行为转化为计算机能够识别的命令,并协调各个硬件配合完成相关命令。
- 软件,是由程序员开发并安装在操作系统的程序(本质上是一大堆的代码),例如:微信、QQ、金山毒霸等。
-
列举常见的操作系统都有哪些。
常用的操作系统有三类:
- win:win7、win10、xp 等
- linux:centos、ubuntu、redhat 等。
- mac:Catalina、Mojave、Sierra 等。
-
简述编译器和解释器的区别和作用。
- 编译器和解释器的作用是将各编程语言的代码进行翻译,从而使得计算机能够识别并执行。
- 编译器,全文翻译,将代码编译成
临时文件,再执行临时文件。 - 解释器,实时翻译,对代码实行边解释边执行。
- JavaScript、Python、PHP、Ruby... 一般称为解释型语言( 脚本语言 ) 。
- C、C++、Go、Java... 一般称为编译型语言。
(二)JS介绍
JS介绍:
JS是直接可以运行在浏览器上的,因为浏览器内置了JS的解释,是一种高级语言,是解释性语言。也就是我们所谓的脚本语言,所谓的脚本语言,就是不需要编译,由解释器去执行。当然现在JS也可以运行在NODE端。
(三)JS三大组成部分
- ECMAScript(最新是ES6):js基础语法核心知识
- DOM(Document Object Model):文档对象模型
操作文档。比如对页面元素进行移动、大小、添加删除等操作
- BOM(Browser Object Model):浏览器对象模型
操作浏览器。比如页面弹窗,检测窗口宽度,存储数据到浏览器等
(四)JS三种写法
0.事件三要素(前置知识)
- 事件源:表示事件发生的场所(元素)
- 事件类型:是click点击,hover悬浮还是之类的事件
- 事件处理程序(监听器):当事件发生时要执行的代码-一般为函数,对应执行里面的函数体操作
1.行内写法
<button onclick="alert('js行内写法')"行内写法</button>
分析:
2.内部写法(常用)
- 推荐将JavaScript代码和编写位置放在body子元素的最后一行;
<button onclick="fn()">内部写法</button>
<script>
function fn(){
// alert表示一个警示框 会阻塞代码向下执行
// 只有点击了确定,alert才会执行完毕
alert('js内部写法');
}
</script>
3.外部写法
//out.js文件
function fn1(){
alert('js外部写法');
}
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入外部的js代码 -->
<script src="./out.js"></script>
</head>
<body>
<button onclick="fn1()">外部写法</button>
</body>
4.乱七八糟写法(微乎其微出现,but可了解下)
//out.js文件
alert('js乱七八糟写法外部文件部分');
<body>
<script src="./out.js">
//无法执行
alert('js乱七八糟写法内部文件部分');
</script>
</body>
二 JS注释+输出/输入语句
(一)JS注释
1.单行注释 ctrl+/
// 1.单行注释
// console.log("hhh")
2.多行注释 alt+shift+a
/* console.log("hhh")
console.log("hhh") */
ps:js多行注释内可以嵌套单行注释,反之...hh好像也可以
(二)JS输出/输入语句
1.JS输出语句
-
弹出对话框-alert()警告
- -confirm()确认
-
// 输出语句1: // 弹出窗口 警示框 掌握! alert('警告一下') // 询问框 了解 confirm('可以吗')
-
控制台-console.log()普通输出
-console.warn()警告输出
-console.error()错误输出
// 输出语句2:
// 输出语句 浏览器控制台打印输出语句 掌握!
console.log('输出语句');
// 变量和纯数字不需要加引号
console.log(111);
console.warn('警告语句')
console.error('错误语句')
- 直接输出至页面-document.write(),里面可以写标签元素
// 输出语句3:
// 在页面上输出
document.write('我是输出语句')
document.write(`<h1>我是输出语句</h1>`)
2.JS输入语句
弹出对话框-prompt()输入对话框
// prompt 信息输入框 掌握!
prompt('请问今年多大?')
3.注意引号
- 使用引号的方式'' "" ``都可以
- 外双内多/外双内单,不能都单或都双
// 注意: 使用引号的方式'' "" ``都可以
document.write('我是"输出"语句')//(外单内双)
document.write("我是'输出'语句")//(外双内单)
// 不能以下写法
// document.write('我是'输出'语句')
// document.write("我是"输出"语句")
三 JS变量
(一)认识变量
什么是变量?为什么使用变量?
// var 声明变量的关键字
// age 变量名
// = 赋值运算符 将右边的值赋值给了左边的变量名 (== ===)
// 18 变量值
// 变量的赋值过程是从右往左的
var age = '18';
age = '19'; //重新赋值
// 一个数据值为100, 在内存空间中开辟一个空间将100放入,将这片内存空间命名为num
var num = 100;
var score = 100;
score = 80; //重新赋值
console.log(score);
(二)变量命名
-
首字符不能是数字 只能是字母 或 _ 或 $
-
其他字符可以是字母、_、$或数字
-
不能使用关键字和保留字符,参考
-
多个单词
- 下划线
- 大驼峰 从第一个单词开始第一个单词的首字母都大写
- 小驼峰 跳过第一个单词从第二个开始每一个单词首字母大写
- 严格区分大小写
- 与标签里class和id属性名的命名比,不能用-
//错误:
// var 1num = 13;
// var 1num = 13;
//正确:
var _num = 13;
var $num = 13;
(三)变量与内存指向关系
情况1:
情况2:
在计算机的内存中创建一块区域保存字符串”malu",name变量名则指向这块区域。然后又再内存中创建了一块域保存字符串”wangcai",name变量名则指向”wangcai“所对应的空间,不再指向"malu"所对应的空间。"malu"所对应的内存空间,无人指向的数据会被标记为垃圾,由解释器自动化回收。
情况3:
在计算机的内存中创建一块区域保存字符串”malu",name变量名则指向这块区域。new_name变量名指向name变量,因为被指向的是变量名,所以自动会转指向到name变量代表的内存区域。
情况四:
情况五:
(四)变量提升
1.声明和赋值在调用之后-变量提升
变量提升:just声明提升而非赋值提升
2.未声明未赋值-报错
// 未声明未赋值,直接报错
// alert(num2);
3.未声明直接赋值(不建议)
<script>
// 不使用var关键字 声明
// 可以这样写但是不建议,不使用var声明的关键字,这个变量是被挂载在window对象
userName = "张三"
// 未声明直接赋值会放到window里,成为它的一个属性
console.log(window);
console.log(window.userName);
</script>
另.声明多个变量两种方式
// 使用一个var声明多个变量
var num, age, sex, username; //声明
//赋值
num = 1;
age = 18;
sex = '男'
// 等同于
var num = 1;
var age = 18;
var sex = '男';
四 JS的数据类型
(一)认识数据类型
1.为什么需要数据类型?
- 给不同的数据分配不同的内存空间,数据类型就是为了让我们合理地使用内存空间
- 内存空间不是无限的,我们需要合理使用
软件运行流程
- 打开某个程序时,先从硬盘中把程序的代码加载到内存中
- CPU执行内存中的代码
使用编译语言是去开发软件的,软件上面的很多的数据,这些数据都是放在内存的。内存空间是有限,绝大部分的编程语言为了合理地使用内存空间,都会把使用到的数据进行分类,分成不同的类型,目的就是为了更加合理的使用内存空间。
typeof介绍与typoef的返回值
- typeof 可用来获取检测变量的数据类型
- "undefined"表示值未定义;
- "boolean"表示值为布尔值;
- "string"表示值为字符串;
- "number"表示值为数值;
- "object"表示值为对象(而不是函数)或 null;
- "function"表示值为函数;
- "symbol"表示值为符号;
2.数据类型的分类
1.Number-数字
正/负数+整数或浮点数,
特殊数字(infinity,-infinity,Number.MAX_VALUE,Number.MIN_VALUE),
NAN(字符串拼接数字时,eg:var num=1+'哈哈')
2.String-字符串 'xxx' + 'xxx' 或 xxx ${} xxx拼接
3.Boolean-true/false
4.undefined-只定义未赋值变量的的默认值
5.null-可以初始化对象,eg:var num=null;
6.Object-var xxx{xxx:xxx,xxx:xxx};
7.BigInt
8.Symbol
其中有5个基本数据类型:
- 基本数据类型
Number String Boolean undefined null BigInt Symbol
-
复杂数据类型
- Object-对象 Array-数组 Function-函数
-
<script> // typeof 检测数据类型 var num=1; console.log(num,typeof num);//number var text="文本"; console.log(text,typeof text);//string(字符串) var bool=false; console.log(bool,typeof bool);//boolean(布尔) </script>
3.数据转换的应用场景
- 用户输入处理
用户输入字符串,我们可能需要将其转换为number类型或其他需要的类型进行计算和验证
- 数据比较
在进行比较操作时,js会自动的进行类型转换
- 数据展示
在将数据展示给用户时,我们可能需要将数据转换为字符串类型以便于显示或者格式化
...
(二)number数据类型
1.number范围
正数负数小数整数,特殊数,NaN(Not a Number)
在js中,无论是小数还是整数,统一是number类型
NaN虽然意思是"不是一个数字",但实际上还是number类型哦~
number有不同进制的表示法
数据的表示范围
2.相关方法
- Number()
- parseInt()
- parseFloat()
-
-
- isNAN() 用于判断是否是一个NaN
是NaN结果是true,否则结果是false
3.代码实操
// 这几个不太熟
//js中运行的结果是Infinity,java中直接会报错
var num3 = 1 / 0;
console.log(num3, typeof num3);//Infinity 'number'
// 特殊数值 NaN (not a number)
var num4 = "hhh" * 2;
console.log(num4);//NaN
console.log(typeof num4);//number
// isNaN() 来判断一个数是否是NaN 两个结果true/false
console.log(isNaN(num4));//true
console.log(isNaN(num3));//false
// 特殊数值 最大值和最小值
var min = Number.MIN_VALUE;
var max = Number.MAX_VALUE;
console.log(min);//5e-324 5*10的负324次方
console.log(max);//1.7976931348623157e+308 1.79*10308次方
var width = 20;
var height = 10;
var age = 18;
var score = 88.8;
console.log(typeof score);//number
// 数字可以进行运算,加减乘除都可
var dblScore = 2 + score;//2+88.8
console.log(dblScore); //90.8
var size = width * height;//20*10
console.log(size);//200
// 特殊数值 无穷大 无穷小
var num1 = Infinity;
console.log(num1);//Infinity
console.log(typeof num1);//number
var num2 = -Infinity;
console.log(num2);//-Infinity
console.log(typeof num2);//number
(三)string数据类型
String 在项目中使用最多,就是所谓的字符串
1.在js中,可以使用"" '' ``引字符
// 单引号
var str1 = 'haha';
// 双引号
var str2 = "hehe";
// 反引号
var str3 = `heihei`;
2.拼接字符串(两种方式)
- Es6 模板字符串(better)
${}
var str7 = `hello ${username} howareyou`
console.log(str7);
- 拼接字符串 +
var str4 = str1 + str2;
console.log(str4);
// var str5 = str1 + str2 + str3;
var str5 = str4 + str3;
var username = "malu"
// hello malu howareyou
var str6 = "hello" + username + "how are you"
console.log(str6);
3. 其他相关tips/方法
- 转义字符,转义就是转变原有的意思
- 通过索引访问访问某个字符串中的某个字符
- 可以求字符串的长度
(四)boolean数据类型(布尔类型)
1.对应值有两个:true、false
// 关系运算符,最终也是布尔类型
console.log(2>1);//true
console.log(2==1);//false
// ! 非,取反
console.log(!2>1);//false
console.log(2!=1);//true
2.在JavaScript中,以下值在if语句中会被自动转换为false
undefinednullfalse(布尔值本身)+/-0(数字0)NaN(非数字)""或''(空字符串)document.all(在非IE浏览器中)
(五)null和undefined数据类型
1.null数据类型
只有一个值null 空
null类型通常用来表示一个对象为空,给一个对象初始化的时候,可以赋值为null
// 给一个已经声明的变量赋值为null进行初始化
var user = null;
user = {
name: '小花',
age: 18
}
2.null和undefined 有什么区别?
undefined通常只用作变量声明未赋值时的默认值
null则是为变量声明未赋值时赋值为空
var uname;
console.log(uname);//und
uname=null;
console.log(uname);//null
// 而undefined一般不这样用,因为本就是默认值
// 如var user2=undefined;
(六)object数据类型
1.拆解分析
// object是一个对象, 也可以称之为容器
//object数据类型是复杂类型,前面讲的都是基本数据类型,往往可以表示一组数据,是其他数据的一个集合
// {}
var obj = {
// name是属性名 小花是属性值
// 属性名-key(键) 属性值-value(值)
// 键值对 key:value
name: '小花',
age: 18,
love: true
}
console.log(obj, typeof obj);
// 访问对象里面的某一个属性
// .叫属性访问运算符 只有对象可以打点
console.log(obj.name);
2.对象模板
// 1.初始化对象
var obj2 = null;
// 2.给对象赋值
obj2 = {
key: value,
key: value,
key: value
}
// 或者直接var obj={key:value,key:value}一步到位
(七)其他数据类型->string
总结: 1)强制转化 a.toString()-这个只可转换Number/Boolean类型 String(a)
2)隐式转化 +
法一 String()构造函数 强制转化
可转Number、Boolean、null、undefined、字面量
法二 使用xx.toString()方法 强制转化
just可转换Number、Boolean类型
法三 + 隐式转换
范围都可以,可转Number、Boolean、null、undefined、字面量
(八)其他数据类型->number
1.string类型(含空串)->number
// string类型(含空串)->number总结:
// 将字符串(包含空串)转为number类型
// 1.Number() 强制转化
// 2.parseInt() parseFloat()
// 3.+ - 隐式转化
特殊:
"123px" 使用Number() + - 被转为NaN
"123px " 使用parseInt() parseFloat() 被转为123 能转则转
"px123px" --转为NaN
- 如果是一个空串,空串是"",转化后, "" => 0
2.其他类型->number
其他类型->number总结:
1.通过Number()
2.+ -
上两个方法其他类型转换时结果一样
true - 1 false - 0 null - 0 undefined - NaN
3.parseInt() parseFloat()
其他数据类型,全都NaN
//举例 undefined - NaN
var i;//und
i+=1;//und =und +1 --> NAN=NAN+1
console.log(i);//NAN
(九)当+碰到Number和String到底谁转谁
1.+Number转String(如 '123'+1,字符串拼接)
var i= '123'+1
console.log(i);//1231
console.log(typeof i);//string
2.+String转Number(如 +'111' ,字符串转数字)
var a= +'111'
console.log(a);//111
console.log(typeof a);//number
3.至于-仅能String转Number
-的话就是无论怎样都转为数字,因为字符串转数字没有-方法
var b= '123'-1
console.log(b);//122
console.log(typeof b);//number
var c=- '123'
console.log(c);//-123
console.log(typeof c);//number
(十)其他数据类型->boolean
通过Boolean() 方法进行转换
哪些数据转成布尔类型会变成false?
- 空串,0,-0,NaN,undefined,null 会转化成false,其它的都会转化成true
五 运算符
(一)概念及分类
// 运算符:具有某些功能的符号 + - * / %
// 操作数:1 + 1 运算符号的两侧的数据叫操作数
// 表达式:任何有值的内容都叫表达式
// 要求:运算的时候,左右两侧的数据必须要保持一致,如果不一致,会发生隐式转化
- // 从功能上划分
// 算数运算符
// 递增递减运算符
// 关系运算符
// 逻辑运算符
// 赋值运算符
- // 从操作数上划分
// 一元运算符 单目运算符 +1
// 二元元素符 双目运算符 1+1
// 三元运算符 三目运算符 三元表达式 xx?xx:xx
(二)算术运算符
1.概念
-
-
- / %
-
数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)。
2.某些特殊情况
// +如果碰到字符串,那么就是字符串拼接
// + 会把number类型隐式转换为String类型
console.log(666 + "123");//666123
// 否则就是相加 number + number
console.log(1 - "666");//-665 -没有隐式转换为字符串的功能
console.log(1 * "666");//666 "666"被隐式转为number类型
//和true(1) false(0)
var d = 100
var e = true;
var f = d + e; //100+1=101
console.log(1 / false);////Infinity
//和null(0)
console.log(666 + null);//666+0 = 666
console.log(1 / null);//Infinity
//取余模为0时有点特殊,结果为NaN
console.log(3 % 0);//NaN
//undefined(NaN)
var und;
console.log(666 + und);//NaN
// NaN和任何数据进行运算,结果都是NaN
console.log(666 + NaN); //NaN
console.log(1 * "文字");//NaN
(三)赋值运算符
概念:将=右边的数据,存储到=左边的变量名对应的内存空间中。
// 简单的赋值运算符 =
// 复杂的赋值运算符 += -= *= /= %=
num1 += 120; //num1=num1+120
//其他类似
赋值运算符有副作用,它的整体也有一个值,如下:
(四)三元运算符
表达式 ? 结果A : 结果B
- 表达式为true,结果A
- 表达式为false,结果B
var res = true ? "hello" : "world"
console.log(res);//hello
var res2 = false ? "hello" : "world"
console.log(res2);//world
var a = 1;
var b = 2;
console.log((a > b) ? "hello" : "world");//world
(五)关系(比较)运算符
1.概念及相关tips
比较运算符(关系运算符)是两个数据进行比较时所使用的运算符
比较运算后,会返回一个布尔值(true / false)作为比较运算的结果
// == === != !== > < >= <=
// 最终返回值是 false true
- 比较时,如果不是数字,会隐式转换为number类型
- 任何数据和NaN作比较 都是false
// false -- 0 true -- 1
// undefined -- NaN
// null -- 0
2.=VS==VS===
// 赋值 =
// 相等 ==
// 全等 ===(先判断类型是否一致,再比较大小)
// ! 取反
// != 不相等
// !== 不全等
// 任何和NaN作比较全部都是false
console.log(NaN === NaN);//f
// 不会判断类型,在比较前已经发生了隐式转换 转换成number类型
console.log(123 == "123");//t
// === 全等 会先比较类型,如果类型不一致,直接返回false
console.log(123 === "123"); //f
// !=不等
console.log(123 != "456");//t
console.log(123 !== "456");//t
console.log(123 !== 456);//t
3.某些特殊情况
// 美国的字符编码集 ASSIC 了解
console.log(1 > "a"); //f 97 1>97
console.log("b" > "a"); //t a=97 b=98
console.log("ab" > "ac"); //f a=97 b=98 c=99
console.log(1 > true); //f
console.log(1 > false); //t
console.log(1 > null); //t
console.log(1 > "123"); //f "123"转换成number是123
console.log(1 > NaN); //f
console.log(1 > undefined);//f und隐式转为NaN
(六)逻辑运算符及逻辑中断
1.逻辑运算符
// 概念:将多个表达式或者值放到一起来获取到一个最终的结果
// && 与 一假即假
// || 或 一真即真
// ! 非 取反
2.逻辑中断
var i = 100;
// ||或 从前往后,哪个为真即输出该值
//这里的中断是第一个值为真时不继续向后执行
console.log(101 || i++);//101
console.log(i);//100
var i = 100;
// &&且 判断到最后,皆为真时输出最后一个值
//这里的中断是第一个值为假时不继续向后执行
console.log(false && i++);//100
console.log(i);//100
(七)递增递减运算符
// ++ --
// ++在前整体是一个新值,++在后整体是一个旧值
var b = 1;
console.log(b);//1
console.log(b++);//1
console.log(b);//2
console.log(++b);//3
console.log(b);//3
(八)运算符的优先级
运算符的优先级有很多,常见的没几个,推荐你记住3个即可:
- 算数优先级优先级 大于 比较运算符
- 比较运算符优先级 大于 逻辑运算符
- 逻辑运算符内部三个优先级 ! > && > ||
直接上代码:
其它优先级:参考
六 分支语句
(一)相关概念
三大流程控制:
// 顺序结构:从上向下,顺序执行代码
// 分支结构:根据条件判断,决定执行代码的哪个分支
// 循环结构: 让特定的代码 重复执行
分支结构
第一种
- // if
- // if else
- // if elseif else
第二种 三元表达式
第三种 switch语句(了解)
注意:
1.if语句中的条件,不管是什么表达式,都会转化成布尔类型
2.if语句后面的{}可以不写,如果不写,只有if后面第1条语句,相当于是{}中的
3.if语句可以嵌套
(二)代码
//第一种情况:单分支if语句
if(条件){
满足条件则执行此代码
}
//第二种情况:双分支if语句法
if(条件){
满足条件执行的代码
}else{
不满足上面条件要执行的代码
}
//第三种情况:多分支if语句法
if(条件1){
满足条件执行的代码
}else if(条件2){
满足条件执行的代码
}else if(条件3){
满足条件执行的代码
}else{
以上都不满足执行代码块
}
七 循环语句
(一)概念
-
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
-
循环三要素:
- 变量起始值
- 终止条件(缺终止条件,循环会一直执行->死循环)
- 变量变化量(用自增/自减)
(二)while和do while循环
-
while(条件){
- //循环体
}
-
do{
- //循环体
}while(条件)
区别:
while:不满足条件一次循环体也不执行
do while:至少执行一次循环体
(三)for循环
for(变量起始值,循环条件;变化值){
循环体
}
一个for嵌套for例子(倒等腰三角形):
// * * * *
// * * *
// * *
// *
for (var i = 1; i <= 4; i++) {
// 打印空格
for (var j = 1; j < i; j++) {
document.write(' ')
}
// 打印*
for (var j = 4; j >= i; j--) {
document.write("* ")
}
// 换行
document.write('<br>')
}
(三)循环中断
- continue// 结束本次循环,继续下次循环
- break// 跳出整个循环,不再进行下次循环
// 跑5圈,第二圈没跑,但是后面跑了
var dinstance = 0;
for (var i = 1; i <= 5; i++) {
if (i == 2) {
// 结束本次循环,继续下次循环
continue;
}
dinstance += 500
}
console.log(dinstance);//2000
// 跑5圈,第二圈没跑,后面都不跑了
var dinstance = 0;
for (var i = 1; i <= 5; i++) {
if (i == 2) {
// 跳出整个循环
break;
}
dinstance += 500
}
console.log(dinstance);//2000
(四)一些练习
1.对数组[5,2,4,2,3,2,5,6,2,5,7,5,3,2,5,6]去重并升序排序
- 使用includes方法
var arr = [5, 2, 4, 2, 3, 2, 5, 6, 2, 5, 7, 5, 3, 2, 5, 6]
var arr1 = [];
arr.forEach(function (item) {
if (!arr1.includes(item)) {
arr1.push(item)
}
})
arr1.sort(function (a, b) {
return a - b;
})
console.log(arr1);
- 使用New Set()方法直接去重(ES6)
var arr = [5, 2, 4, 2, 3, 2, 5, 6, 2, 5, 7, 5, 3, 2, 5, 6]
var set=new Set(arr)
console.log(set);
2.百元买百鸡
// 百钱买百鸡(鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?)
// 100元 公鸡/5元(a) 母鸡/3元(b) 小鸡*3/ 1元(c)
// 100元 公鸡 100/5==20
// 100元 母鸡 100/3==33
// 100元 小鸡 100*3=300
for (var a = 0; a <= 20; a++) {
// 考虑:在买0只公鸡的情况下,要么多少只母鸡,多少只小鸡
// 考虑:在买1只公鸡的情况下,要么多少只母鸡,多少只小鸡
// ...
// 考虑:在买20只公鸡的情况下,要么多少只母鸡,多少只小鸡
for (var b = 0; b < 34; b++) {
// 考虑:在买0只母鸡的情况下,要么多少只小鸡
// 考虑:在买1只母鸡的情况下,要么多少只小鸡
// ...
// 考虑:在买33只母鸡的情况下,要么多少只小鸡
for (var c = 0; c <= 300; c++) {
if ((a + b + c) === 100 && (5 * a + 3 * b + c / 3) == 100) {
console.log("公鸡:" + a + "母鸡:" + b + "小鸡:" + c)
}
}
}
}
3.斐波那契数列
// 斐波那契数列,输入斐波那契数列的个数,打印斐波那契数列
// 如输入了10,求斐波那契数列前10个数字
// 10
var num = +prompt('请输入斐波那契数列的个数(大于2)');
var x = 1;
var y = 1;
var z = 2; //表示两个数字的相加和
for (var i = 1; i <= num; i++) {
if (i == 1 || i == 2) {
console.log(1);
} else {
z = x + y;
x = y;
y = z;
console.log(z);
}
}
八 函数
(一)初识函数
函数,可以当做是一大堆功能代码的集合。就是某段代码的封装,这段代码帮助我们完成某一个功能。默认情况下,JS引擎也帮我提供了一些函数,我们也可以编写自己的函数。
什么时候会使用到函数:
- 有重复代码,用函数增加代码的重用性。
- 代码太长,用函数增强代码的可读性。
以前我们变成是按照业务逻辑从上到下逐步完成,称为:面向过程编程;现在学了函数之后,利用函数编程称为:函数式编程。
函数声明和函数表达式:
- 使用function关键字来声明一个函数,也可以把一个函数赋值给一个变量,我们叫函数表达式
直接上代码:
函数声明的注意细节:
- 函数名的命名规则和前面变量名的命名规则是相同的
- 函数定义完后里面的代码是不会执行的,函数必须调用才会执行
- 函数要尽量做到见名知意,学习时,使用foo,bar,fn,gn....
- 由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 getSum
函数调用:
- 调用函数是让已存在的函数为我们所用
- 可以是自己写的函数,也可以是系统中内置的,也可以是第三方的
- 调用的时候千万不要忘记添加小括号
直接上代码:
(二)函数写法:匿名函数|具名函数|箭头函数
1.具名函数
function fn2(){
console.log("我是具名函数")
}
fn2()
2.匿名函数
//函数表达式
var fn1=
//匿名函数
function(){
console.log("我是匿名函数")
}
//匿名函数的调用与具名函数相同
fn1()
3.箭头函数
var fn1 = (a) => {
console.log(1);
}
fn1(1)
- 情况一:如果内容只有一行 可以省略{}
var fn1 = () => console.log(11);
- 情况二:如果参数只有一个 可以省略()
var fn1 = item => console.log(11);
- 情况三: 如果你的函数体里面的返回值返回的是一个对象
var fn1 = () => ({ a: 1 })
(三)作用域(局部变量和全局变量)
局部变量和全局变量:
- 局部变量就是只能在一定范围内使用,一般在函数内部的var变量都是局部变量, 函数的形参****也是局部变量
- 全局变量就是在全局哪里都可以使用
- 函数体内部所对应的空间就是局部作用域
- 函数体外部所对应的空间就是全局作用域
1.变量var x VS x
- var x和x作全局变量时,都是window对象身上的属性
- var x 在函数体内时不是全局变量,是局部变量
- var x变量声明提升,但x变量不会声明提升
- var x不能用delete()方法删掉,但x可以用delete()方法删掉
2.示例代码
(四)函数的参数(形参和实参)
在定义函数时,如果在括号中添加 变量 ,我们称它为函数的形式参数
实际调用函数时,如果在括号中有数值传入,我们称它为函数的实际参数
(五)函数的返回值
函数本质也是一个数据,数据类型是function,如下:
So调用一个函数,函数是可以给我们返回一个数据的
- 通过return关键字实现返回,直接上代码:
- 如果函数没有写return,它默认返回und,如下:
(六)函数是否加()的区别
- fn() 调用函数
- console.log(fn()) 调用函数并打印函数(返回)值
- console.log(fn) 打印函数体
function fn() {
console.log(123);//123
}
//fn()调用函数
fn()
// 打印fn()--调用函数后打印函数(返回)值
console.log(fn()); //123 und
// 打印fn--打印函数体
console.log(fn);//函数体
九 数组
(一)数组介绍
前面写的多个数据类型,有字符串,数字,布尔,und,null,这些数据类型叫基本数据类型。还有复杂数据类型,复杂数据类型有数组,有函数,有对象。数据是一个容器,是一个有序的集合,它里面可以放一堆的数据。
数组叫array,数组中的每一个数据,叫元素(elements); 每一个元素都有一个索引,也叫下标(index) ,索引是从0开始的;数组中元素的个数,叫数组的长度(length) 。
数组中放的数据的类型可以不一样,可以放任意的数据类型。
代码如下:
(二)操作数组
1.创建数组
- 通过字面量的形式的创建
var arr2 = ["a", "b", true, 123, 600, undefined, null];
- 通过new Array()的形式的创建
var arr3 = new Array("hello", "world", 111, null);
当new Array(n),参数n是一个数字时,创建为长度为数字大小的数组。
2.数组元素的CRUD(原数组被改变)
a.添加元素
- push 尾部——返回值为新增元素后的数组长度
- unshift 头部——返回值为新增元素后的数组长度
- splice 任意位置——返回值为删除的元素数组
代码演示:
b.删除元素
- pop 尾部——返回值为数组删除的元素
- shift 头部——返回值为数组删除的元素
- splice 任意位置——返回值为删除的元素数组
代码演示:(增删都有)
/* 1.push增 + pop删 数组尾部元素 */
var arr = ['a', 'b', 'c', 1, 2, 3];
console.log(arr);
//push(),返回值为新增元素后的数组长度
var arr1 = arr.push(4, 5);
console.log(arr1);
console.log(arr);
//pop(),返回值为数组删除的元素
var arr2 = arr.pop();
console.log(arr2);
console.log(arr);
/* 2.unshift增 + shift删 数组头部元素*/
var arr = ['a', 'b', 'c', 1, 2, 3];
console.log(arr);
//unshift(),返回值为新增元素后的数组长度
var arr1 = arr.unshift(0, 1);
console.log(arr1);
console.log(arr);
//shift(),返回值为数组删除的元素
var arr2 = arr.shift();
console.log(arr2);
console.log(arr);
/* 3.splice()删增数组任意位置元素*/
var arr = ['a', 'b', 'c', 1, 2, 3];
console.log(arr);
//splice(),返回值为删除的元素数组
//从索引位置0开始,删除2个元素,并从0索引位置开始新增'a1','b1'俩元素
var arr1 = arr.splice(0, 2, 'a1', 'b1');
console.log(arr1);
console.log(arr);
//从索引位置1开始,删除1个元素(即删除arr[1]本身),不新增
var arr2 = arr.splice(1, 1);
console.log(arr2);
console.log(arr);
//从索引位置1开始,不删除,仅新增1个元素
var arr3 = arr.splice(1, 0, 'hhh');
console.log(arr3);//返回空数组[]
console.log(arr);
var arr4 = arr.splice(-1, 0, 'hhh');//splice第一个参数为负数,则是从位置倒数开始
//注意 倒数是-1开始 不是0
console.log(arr4);//返回空数组[]
console.log(arr);
c.修改元素
d.访问元素
// 访问元素一(掌握)
var arr2 = ["a", "b", "c"];
// 通过[索引]来访问某一项元素
console.log(arr2[0]); //a
console.log(arr2[1]); //b
console.log(arr2[2]); //c
// 如果访问一个不存在的元素 ,得到und
console.log(arr2[3]); //und
// 访问元素二(了解)
var arr3 = ["a", "b", "c"];
console.log(arr3.at(0)); //a
console.log(arr3.at(3)); //und
// at 可以写负值 如果at中的参数是负数,是从后往前找元素
console.log(arr3.at(-1));//c
console.log(arr3.at(-2));//b
3.数组的查找
// indexOf lastIndexOf查找数组的某个元素的索引
// includes 查找数组是否包括某个元素
// find(function(){}) 查找元素
// findIndex(function(){}) 查找元素对应的索引
//返回索引不存在时,一般返回-1
// 元素不存在,一般返回undefined ps:includes()是false
a.indexOf lastIndexOf 查找数组的某个元素的索引(方向不同)
var arr1 = ["z3", "l4", "w5", "z6", "t7", "l4"];
// 1.indexOf 从左往右查找数组的某个元素的索引
console.log(arr1.indexOf('l4'));//1
//如果元素不在数组中,返回值为-1
console.log(arr1.indexOf("xxx"));//-1
// 2.lastIndexOf 从右往左查找数组的某个元素的索引
console.log(arr1.lastIndexOf('l4'));//5
b.includes 查找数组是否包括某个元素
// 3.includes 查找数组是否包括某个元素 返回一个布尔值true/false
console.log(arr1.includes('xxx'));//false
console.log(arr1.includes('z3'));//true
c.find 查找元素
// 4.find 查找元素
// 函数的参数是一个函数,叫高阶函数
/* 语法 arr.find(function(item,index,arr){
}) */
//参数:
// item 表示数组中的每一个元素
// index 表示每一个元素对应的索引
// arr 表示此数组
var arr2 = ["z3", "l4", "w5", "z6", "t7", "l4"];
// find 自带遍历功能
//return item == "z3";元素在其中
var res1 = arr2.find(function (item, index, arr) {
console.log(item);
console.log(index);
console.log(arr);
return item == "w5";
});
//return item == "xxx";元素不在其中
var res2 = arr2.find(function (item, index, arr) {
return item == "xxx";
});
console.log(res1);//w5
console.log(res2);//undefined
d.findIndex 查找元素对应的索引
// 5.findIndex 查找元素对应的索引 与find语法类似
// 语法:arr.findIndex(function(item,index,arr){
// })
var res3 = arr2.findIndex(function (item, index, arr) {
return item == "z3";
});
//return item == "xxx";元素不在其中
var res4 = arr2.findIndex(function (item, index, arr) {
return item == "xxx";
});
console.log(res3);//0
console.log(res4);//-1
4.数组的遍历(及对象的遍历)
a利用普通的for循环进行遍历,如下:
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
b使用for (var index in arr)进行遍历,如下:
for (var index in arr) {
// index -- 索引
console.log(arr[index]);
c使用for (var item of arr)进行遍历,如下:
for (var item of arr) {
// item -- 每一项
console.log(item);
}
d使用forEach (function(){})进行遍历,如下:
arr.forEach(function (item,index,arr) {
// console.log(item);
// 让数组中的每个元素都执行一次对应的方法
console.log(item + "111");
});
e使用=>箭头函数进行遍历
var arr = [1, 2, 3]
// 箭头函数
arr.forEach((item) => { console.log(item) })
arr.forEach(item => console.log(item))
PS:对象的遍历for (var key of obj)
只能用for in遍历的是对象的键值,再通过键来获取对应的值
var obj = {
// key:value;
name: "zhangsan",
age: 18,
height: 180
}
// for in 循环遍历的是对象的键值,再通过键来获取对应的值
for (var key in obj) {
console.log(key);
console.log(obj[key] );
}
// 遍历对象不能使用for of
for (var item of obj) {
console.log(item); //obj is not iterable 对象不可迭代
}
PS:特殊情况-类数组
用document.querySelectAll()/document.getElementsByXXX()得到的对象是一个类数组对象不是数组
所以forEach(),for of不能用,for in最好也别用
PS:字符串的遍历for (var item of str)
var str1 = "hello";
// for of
for (var item of str1) {
console.log(item);
}
5.数组的映射、过滤和累加
map 映射,对数组的每一个元素进行加工,返回一个新数组
filter 过滤 会创建一个新数组, 不会改变原数组
reduce 累加 一个和
a.map: 映射——对数组的每一个元素进行加工
// 会返回一个新数组
// 语法 arr.map(function(){
// })
var res1 = arr.map(function (item) {
return item + "111";
});
console.log(arr);// ['z3', 'l4', 'w5', 'z6', 't7', 'l4']
console.log(res1);// ['z3111', 'l4111', 'w5111', 'z6111', 't7111', 'l4111']
b.filter:过滤
// 会创建一个新数组,不会改变原数组
// 语法 arr.filter(function(item){
// })
var arr2 = [2, 3, 4, 5, 6, 7, 234, 34, 34, 2];
var res2 = arr2.filter(function (item) {
return item >= 10;
});
console.log(arr2);//[2, 3, 4, 5, 6, 7, 234, 34, 34, 2]
console.log(res2);//[234, 34, 34]
c.reduce:累加
var arr3 = [1, 2, 3, 4, 5, 6];
var res3 = arr3.reduce(function (prev, next) {
return prev + next;
// 第一次:prev 100 next 1
// 第二次:prev 101 next 2
// 第三次:prev 103 next 3
// 第四次:prev 106 next 4
// 第五次:prev 110 next 5
// 第六次:prev 115 next 6
// 结果:121
}, 100);//100是prev的初始值
console.log(res3);//121
6.数组的排序及翻转(原数组被改变)
- sort 排序——ASCII/降序/升序
- reverse 数组翻转
a.sort 排序——ASCII/降序/升序-原数组被改变
// 1.sort 排序——根据ASCII比较,升序
// 语法:arr.sort()
var arr = [2, 45, 6, 7, 8, 34, 5, 35];
console.log(arr.sort());//从最高位单位单位比较而非整体数值
console.log(arr); //原数组被改变
var arr2 = ["a", "d", "c", "b", "e"];
console.log(arr2.sort());
// 2.sort 从小到大 升序return a - b;
// 语法:arr.sort(function(a,b){
// return a-b;
// })
// 如果(a, b)=> a - b返回小于0的值,那么a将被排列到b之前
// 如果(a, b)=> a - b返回0,那么a和b的顺序不变
// 如果(a, b)=> a - b返回大于0的值,那么b将被排列到a之前
arr.sort(function (a, b) {
return a - b;
});
console.log(arr);
// 3.sort 从大到小 降序return b - a;
// 语法:arr.sort(function(a,b){
// return b-a;
// })
arr.sort(function (a, b) {
return b - a;
});
console.log(arr);
b.reverse 数组翻转-原数组被改变
// 4.reverse 数组翻转
// 语法:arr.reverse()
console.log(arr.reverse());
console.log(arr); //原数组被改变
7.数组的合并与截取
- slice() 截取数组元素 特点:包前不包后
- concat() 合并数组 把多个数组合并成一个数组
a.slice() 截取数组元素
// 1.slice() 截取数组元素的新数组,不改变原数组
var arr1 = [0, 1, 2, 3, 4, 5];
// slice(start,end) 包前不包后
var res = arr1.slice(1, 3)
console.log(arr1.slice(1, 3));//[1,2]
// slice(start) 从start开始到最后
console.log(arr1.slice(1));//[1,2,3,4,5]
// start为负数时 从后-1开始往前数第负数个 包前不包后
console.log(arr1.slice(-4));//[2, 3, 4, 5]
console.log(arr1.slice(-4,-1));//[2,3,4]
// slice() 整个数组
console.log(arr1.slice());//[0,1,2,3,4,5]
b.concat() 合并数组
// 2.concat() 合并数组
var arr2 = ['hh', 'xixi'];
var arr3 = [null, true];
// 合并一个数组
console.log(arr1.concat(arr2));//[0, 1, 2, 3, 4, 5, 'hh', 'xixi']
// 合并多个数组
console.log(arr1.concat(arr3,arr2));//[0, 1, 2, 3, 4, 5, null, true, 'hh', 'xixi']
8.检索数组里面的某一项是否符合条件
a.some() 一真全真
// 作用:检索数组里面的某一项是否符合条件 一真全真
let arr3 = [3, 6, 9, 12]
let res6 = arr3.some(function (item, index) {
return item == 12;
// return item == 2;
})
console.log(arr3);
console.log(res6);//true
b.every() 一假全假
// 作用:检索数组里面的某一项是否符合条件,如果数组中检测到有一个元素不满足,则整个表达式返回 false 一假全假
let arr4 = [3, 6, 9, 12]
let res7 = arr4.every(function (item, index) {
return item < 12;
})
console.log(arr4);
console.log(res7);//true
(三)数组和字符串之间相互转化
- join 数组.join("拼接符") 把数组转化成字符串
- split 字符串.split("分隔符") 把字符串转化成数组
a.join() 把数组转换为字符串
// 1.join() 把数组转换为字符串
console.log(arr1.join());//0,1,2,3,4,5 默认分隔符为,
//join('-') 参数为分隔符
console.log(arr1.join('-'));//0-1-2-3-4-5
b.split() 把字符串转换为数组
// 2.split() 把字符串转换为数组
var str='nihao-aaaa-bbb-ccc';
console.log(str.split());//['nihao-aaaa-bbb-ccc']
//split('-') 参数为分隔符
console.log(str.split('-'));// ['nihao', 'aaaa', 'bbb', 'ccc']
(四)伪数组和数组相关
a.Array.isArray()判断是否为数组
b.Array.from() 把伪数组转换为数组
十 字符串
和数组是不一样的 , 字符串不可以被改变字符,不可以重新赋值
var str1 = "hello";
str1[4] = "O"
console.log(str1);//hello 未改变
(一)创建字符串
// 1)通过字面量的形式来创建一个字符串
var str1 = "hello";
console.log(str1);
// 获取字符串的长度 length 长度
console.log(str1.length);//5
// 2)通过 new String()来创建一个字符串
var str2 = new String("world")
console.log(str2);
console.log(str2.length);
(二)遍历+访问字符串字符
a.遍历字符串字符
// for循环
for (var i = 0; i < str1.length; i++) {
console.log(str1[i]);
}
// for of
for (var item of str1) {
console.log(item);
}
b.访问字符串字符
// 使用方式1 :通过字符串的索引 str[0]
var str = "hello"
console.log(str[1]);//e
console.log(str[4]);//o
console.log(str[6]);//und
// 使用方式2 通过str.charAt(0)
console.log(str.charAt(0));//h
console.log(str.charAt(4));//o
console.log(str.charAt(6));//空串(空字符串)
// 区别:如果通过索引去访问一个不存在的元素
(三)操作字符串
- indexOf() 从长串中找到子串 返回值是子串的首字母的索引
- includes 包含 长串中是否包含子串 返回true false
- startsWith 判断是否以什么开头 返回true false
- endsWith 判断是否以什么结尾 返回true false
- toLowerCase(): 将所有字符转成小写
- toUpperCase(): 将所有字符转成大写
- replace 替换/替代 替换字符串
-
- concat 拼接字符串
- trim() 去掉前后空格
// indexOf() 从长串中找到子串
var str1 = "my name is wang";
console.log(str1.indexOf("name"));//3
console.log(str1.indexOf("my"));//0
// 返回值是-1的时候,说明在长串中找不到子串
console.log(str1.indexOf("lee"));//-1
// ----------------------------
// includes 包含 长串中是否包含子串
var str2 = "my name is wang";
console.log(str2.includes("name")); //true
console.log(str2.includes("lee")); //false
// ----------------------------
// startsWith 判断是否以什么开头
// endsWith 判断是否以什么结尾
var str3 = "my name is wang";
console.log(str3.startsWith("my"));//true
console.log(str3.startsWith("you"));//false
console.log(str3.endsWith("wang"));//true
console.log(str3.endsWith("lee")); //false
// ----------------------------
// toLowerCase 大写转小写
// toUpperCase 小写转大写
var str22 = "HELLO";
var str33 = "hello";
console.log(str22.toLowerCase());//hello
console.log(str33.toUpperCase());//HELLO
// ----------------------------
// replace 替换/替代 替换字符串
var str4 = "my name is wang";
var newStr = str4.replace("my", "you")
console.log(newStr);
// ----------------------------
// 拼接字符串 + concat
var str5 = "hello";
var str6 = "world";
console.log(str5 + str6);
console.log(str5.concat(str6));
// ----------------------------
// trim() 掌握! 去掉前后空格
var str7 = " 前端 ";
console.log(str7);
console.log(str7.trim());
(四)数组和字符串之间相互转化
- join 数组.join("拼接符") 把数组转化成字符串
- split 字符串.split("分隔符") 把字符串转化成数组
a.join() 把数组转换为字符串
// 1.join() 把数组转换为字符串
console.log(arr1.join());//0,1,2,3,4,5 默认分隔符为,
//join('-') 参数为分隔符
console.log(arr1.join('-'));//0-1-2-3-4-5
b.split() 把字符串转换为数组
// 2.split() 把字符串转换为数组
var str='nihao-aaaa-bbb-ccc';
console.log(str.split());//['nihao-aaaa-bbb-ccc']
//split('-') 参数为分隔符
console.log(str.split('-'));// ['nihao', 'aaaa', 'bbb', 'ccc']
十一 对象
(一)创建对象
创建方式一:字面量的方式
创建方式二:通过new Object的方式创建
PS:对象的key与value同名时可以只写一个
let name='name'
function fn(){
console.log(this);
}
let obj={
// key与value同名时可以只写一个
name,
fn
}
console.log(obj)
//Object:
//fn: ƒ fn()
//name: "name"
代码举例
// 创建方式一:字面量的方式
var obj = {
name: "zhangsan",
age: 18,
isMarry: false,
// 如果一个函数位于一个对象中,这个函数叫方法
eat: function () { //eat是一个方法
console.log("eat..");
}
}
// 创建方式二:通过new的方式创建
var obj1 = new Object();
obj1.name = "wang";
obj1.age = 18;
console.log(obj1);
(二)操作对象(CRUD)
var obj = {
name: "wang",
age: 18,
isMarry: false,
eat: function () { //eat是一个方法
console.log("eat...");
}
}
// 访问属性 查
console.log(obj.name);
//联想前面的for in 遍历对象key后obj[key]获取对应value
console.log(obj["name"]);
// 添加属性 增
obj.address = "zhengzhou";
console.log(obj);
// 修改属性 改
obj.name = "lee";
console.log(obj);
// 删除属性
delete obj.address;//delete是一个运算符,用来删除某个对象上的属性
// 访问对象身上不存在的属性,得到und
console.log(obj);
console.log(obj.hobby);//undefined
(三)Math对象
- Math.PI 圆周率
- Math.floor(n) n向下取整
- Math.ceil(n) n向上取整
- Math.round(n) n四舍五入取整
- Math.random() 生成 [0,1) 的随机数
- Math.pow(x, y) 返回x的y次方
- Math.max(a,b,c,d,e) 返回a,b,c,d,e的最大值(参数可以用...数组)
- Math.min(a,b,c,d,e) 返回a,b,c,d,e的最小值(参数可以用...数组)
// 圆周率
console.log(Math.PI);
// floor 本意是地板的意思 向下取整
console.log(Math.floor(3.8));//3
console.log(Math.floor(3.2));//3
// ceil 本意是天花板的意思 向上取整
console.log(Math.ceil(3.2));//4
console.log(Math.ceil(3.9));//4
// round 本意是环绕的意思 四舍五入取整
console.log(Math.round(3.5));//4
console.log(Math.round(3.2));//3
// random 本意是随机的意思,生成0-1的随机数 包含0 但是不包含1
console.log(Math.random());
// 随机生成一个5-50的整数 5<=x<=50
var randomNum = Math.round(Math.random() * 45) + 5
console.log(randomNum);
// pow 返回x的y次方
console.log(Math.pow(3, 4));//81
(四)Date对象
new Date().xxx 获取日期时间(年/月 +1/日/时/分/秒/毫秒/周)
// 获取日期和时间
var date = new Date();//记得这个就可以.得到其他
console.log(date);//Mon Mar 18 2024 16:09:23 GMT+0800 (中国标准时间)
// 获取日期
console.log(date.toDateString());
// 获取时间
console.log(date.toTimeString());
console.log(date.getFullYear());//年
console.log(date.getMonth()+1);//月 +1
console.log(date.getDate());//日
console.log(date.getHours());//时
console.log(date.getMinutes());//分
console.log(date.getSeconds());//秒
console.log(date.getMilliseconds());//毫秒
console.log(date.getDay());//周
Date获取Unix时间戳: 时间戳:它是一个整数值,表示自1970年1月1日00:00:00 UTC以来的毫秒数。
方式一:new Date().getTime()
方式二:new Date().valueOf()
方式三:+new Date()
方式四:Date.now()
十二 小点
1.判定是否存在时如何选择:contains|includes|has
contains ( 操作DOM)
contains作为包含,出现在Element.classList.contains和Node.contains这两个api上,它们都是DOM API,也就是说在操作DOM时遇到包含那就是contains了
includes ( 数组和字符串 )
includes作为包含出现在Array. prototype.includes和String.prototype .includes上,即js中我们常用的数组和字符串上会用includes
has ( key参数 )
has作为判断包含的方法出现在Map/Set/WeakMap/WeakSet/Reflect/FormData上。可以发现与上面的includes 不同,这些has中传入的都是具有唯一性的key参数,即js中如果包含是具有唯一性的包含的话用has,否则是includes
2.返回值区分:undefined、null、-1
PS:undefined
- 在严格模式(js高级)中的独立函数调用没有默认绑定,this指向und
- 解构(ES6)不匹配
- 访问数组获取不存在索引的元素
PS:null
- .nodeValue获取元素节点的文本内容时返回null,因为它是用来获取非元素节点的文本内容的