前言
JavaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。所谓的前端验证,就是指检查用户输入的内容是否符合一定的规则。比如:用户名的长度,密码的长度,邮箱的格式等。但是,有的同学可能会有疑问,这些验证,后端不也可以进行验证吗?确实,后端程序的确可以进行这些验证,但你要清楚,在1995年那个年代,网速是非常慢的,向后端发送一个请求,浏览器很久才能得到响应,那这无疑是一种非常不好的用户体验。
为了解决前端验证的问题,当时的浏览器巨头NetScape(网景)公司就开发出一种脚本语言,起初命名为LiveScript,后来由于SUN公司的介入更名为了JavaScript。但是你要清楚,Java和JavaScript是没有什么关系的,只不过当时Java非常流行,为了蹭热度,才将LiveScript更名为JavaScript,它们的关系就像雷锋和雷峰塔的关系一样,没啥关系。
js--作用
1.是一种解释性脚本语言(代码不进行预编译)。
2.主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。
3.可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
5.跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、 Mac、Android、iOS等)。
6.Javascript脚本语言同其他语言一样,有它自身的基本数据类型,表达式和算术运算符及程序的基本程序框架。Javascript提供了四种基本的数据类型和两种特殊数据类型用来处理数据和文字。而变量提供存放信息的地方,表达式则可以完成较复杂的信息处理。
可以实现web页面的人机交互。
js--组成
1.ECMAScript:JavaScript的核心
2.DOM:Document Object Model(文档对象模型)
3.浏览器对象模型Browser Object Model(BOM)
js写法
1.行内式:
<button οnclick="alert('今天天气很好!');">今天天气?</button>
虽然可以写在标签的属性中,但是结构与行为耦合,不方便维护,不推荐使用
方式二:
<a href="javascript:alert('你点疼我了!!');">点我</a>
2.(页面式):
<body>
……
<script type="text/text/javascript">
alert('我出现了')
</script>
</body>
注意事项:
<script></script>标签中的js代码一版写在文档的尾部;
网页是从上而下加载的,而js代码通常是给变迁添加交互(操作元素),所以需要先加载html,否则如果执行js代码时html还没有被加载,那么js代码将无法添加交互(操作元素)
html页面中出现<script>标签后,就会让页面暂停等待脚本的解析和执行,无论当前脚本时内嵌式还是外链式,页面的下载和渲染都必须停下来等待脚本的执行完成才能继续。
所以如果把js代码写在head中,那么js代码执行完毕之前后续页面无法被加载。
3.:外链式
<script type="text/javascript" src="01-js书写格式.js"></script>
注意事项
外链式的script代码块中不能编写js代码, 即便写了也不会执行
<script type="text/javascript" src="index.js">
alert("今天天气很好!"); // 不会被执行
</script>
js输出方式:
alert("Hello, World!");
控制浏览器弹出一个警告框
document.write("Hello World!");
可以向body中输出一个内容
console.log("Hello World!");
向控制台输出一个内容
console.warn("警告输出!");
console.error("错误输出!");
prompt("Hello, World!");
在网页中弹出输入框,一般用于接收用户输入的信息
comfirm("Hello,JavaScript!");
在网页中弹出提示框,显示信息,该方法一般与if判断语句结合使用
JS严格区分大小写
comfirm("Hello,JavaScript!"); // 正确
COMFIRM("Hello,JavaScript!"); // 错误
JS标识符
命名规则
1. 标识符中可以含有字母、数字、_、$
2. 标识符不能以数字开头
3. 标识符不能是ES中的关键字或保留字
4. 标识符一般都采用驼峰命名法
首字母小写,每个单词的开头字母大写,其余字母小写
比如: myName, yourName, itLike, ....
5. 在JS底层保存的标识符采用的是Unicode编码,所以UTF-8中所有的字符都可以作为标识符
js--注释
单行注释:为了提高代码的可读性, JS 与css— 样, 也提供了注释功能。
js 中的注释主要有两种, 分别是单行注释和多行注释。
单行注释的注释方式如下:
/ / 我是一行文字, 不想被JS引擎执行,所以注释起来
/ / 用来注释单行文字(快捷键ctrl + /)
多行注释
多行注释的注释方式如下.
/*
获取用户年龄和姓名
并通过提示框显示出来
*/
/ * * / 用来注释多行文字( 默认快捷键alt +shift+a)
快捷键修改为ctrl + shift +/
js常见的语句 :
- if 语句
- do while 语句
- while 语句
- for 语句
- for in 语句
- for of 语句
- break , continue 语句
- with 语句
- switch 语句
if 语句时最常用的语句之一
语法1: if ( 表达式 ) { 表达式成立的逻辑 } else { 表达式不成立的逻辑 }
语法2: if ( 表达式1 ) { 表达式1成立的逻辑 } else if (表达式2) { 表达式2成立的逻辑 } else {表达式1和2都不成立的逻辑}
const num = 5;
// if else
if (num % 2 === 1) {
console.log('num 除 2 的余数是1');
} else {
console.log('num 除 2 的余数不是1');
}
// 最终结果 : 输出 'num 除 2 的余数是1' 原因: num / 2 的余数是 1 满足条件
// if else if
if (typeof num === 'number') {
console.log('num 的类型是数字');
} else if (num === '5') {
console.log('num 全等于 "5"');
} else {
console.log('num 不满足上面的条件');
}
// 最终结果: 输出 'num 的类型是数字' 原因: typeof num === 'number' 条件成立
do while 是一种后循环语句,
先执行一次do语句块中的代码, 再依据条件是否成立判断是否继续执行do语句块中的代码 , 简单来说就是我先做了再看看能不能做 .
let str = 'a'
do {
str = str + String.fromCharCode(str.charCodeAt() + str.length);
} while (str.length < 7);
console.log(str); // abcdefg
// 简单梳理一下 : 以上代码意思就是判断 str 变量的长度是否小于7, 如果小于7就在后面拼接上一位
字符后面一位的字符
// 知识点 : String.fromCharCode(number) 将数字编码转换成对应的字符串
// charCodeAt() 返回字符串对应的编码
while 语句和 if 语句类似, 当条件满足时, 执行代码块 . 唯一的区别就是 if 语句可以写else
语法: while (condition 条件) { 条件满足执行的逻辑 } ;
// while 语句
let num = 1;
while (num < 5) {
num += 1
};
console.log(num);
// 代码说明 : 当 num 变量小于 5 的时候, 让 num 变量 +1
// 当 num 值为 4 的时候, 满足条件 num + 1 = 5 , 而 5 不小于 5 就退出循环
// 最终 num 的值为 5
for 语句也是 js 中常用的语句之一, 主要用来做循环 .
语法: for (init (初始变量) , expression(条件) , loop-expression(循环体执行完的逻辑)) { 循环体 }
let arr = [];
for (let i = 1; i < 10; i++) {
arr.push(i)
}
console.log(arr);
// 代码说明: 在循环前定义 i 为 1, 当 i < 10 的时候往数组 arr 中追加 i 变量 , 最后让 i + 1
// 执行顺序 1. let i = 1
// 2. i < 10
// 3. arr.push(i)
// 4. i++
// 5. i < 10
// 6. arr.push(i)
// 7. i++ ............
// 当 i 不小于 10 时, 退出循环
--------后面就不一一列举了
js的执行原理:
计算机运行原理
数据类型
在JS中一共有九种数据类型,有六种基本数据类型,分别是:String (字符串)、Number (数值)、Boolean (布尔值)、Null (空值)、Undefined (未定义)、Object(对象)
String 字符串
- 在JS中字符串需要使用引号引起来
- 使用双引号或单引号都行,但是不要混着用
- 引号不能嵌套,双引号不能放双引号,单引号不能放单引号
- 在字符串中我们可以使用\作为转义字符,当表示一些特殊符号是可以使用 \进行转义
- \n表示换行、\t制表符(空格)、\表示(2个斜杠出来1个斜杠)
Number 数值
在JS中所有的数值都是Number类型,包括整数和浮点数(小数)
- Js中可以表示数字的最大值
- Number.MAX_VALUE
- 1.7976931348623157e+308
- Number.MIN_VALUE 大于0的最小值
- 5e-324
- 如果使用Number表示的数值超过了最大值,则会返回一个
- Infinity(无穷大)
- 表示一个正无穷
- -Infinity
- 表示一个负无穷
- 使用typeof检查Infinity也会返回一个number
- NaN表示一个特殊的数字,表示Not A Number
- 使用typeof检查NaN也会返回一个number
Boolean 布尔值
- 布尔值只有两个,主要用来逻辑判断
- true:表示真 false:表示假
- 使用typeof检验一个布尔值时,会返回一个boolean
Null 空值
Null的值只有一个,就是null(空值)
null的这个值专门用来表示一个为空的对象
使用typeof检测一个null值时,会返回一个object(对象)
Undefined 未定义
Undefined类型的值只有一个,就是Undefined(未定义)
当声明一个变量,但不给这个变量赋值时,它的值就是Undefined
使用typeof检查Undefined值时,也会返回一个Undefined
Object(对象)
- 万物皆对象,没有对象new一个新对象
栈
是一种运算受限的线性表,其限制是指只仅允许在表的一端进行插入和删除操作,这一端被称为栈顶(Top),相对地,把另一端称为栈底(Bottom)。把新元素放到栈顶元素的上面,使之成为新的栈顶元素称作进栈、入栈或压栈(Push);把栈顶元素删除,使其相邻的元素成为新的栈顶元素称作出栈或退栈(Pop)。这种受限的运算使栈拥有“先进后出”的特性(First In Last Out),简称FILO。
栈分顺序栈和链式栈两种。栈是一种线性结构,所以可以使用数组或链表(单向链表、双向链表或循环链表)作为底层数据结构。使用数组实现的栈叫做顺序栈,使用链表实现的栈叫做链式栈,二者的区别是顺序栈中的元素地址连续,链式栈中的元素地址不连续。
栈的结构如下图所示:
栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。参考如下代码:
int main()
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
}
堆
是一种常用的树形结构,是一种特殊的完全二叉树,当且仅当满足所有节点的值总是不大于或不小于其父节点的值的完全二叉树被称之为堆。堆的这一特性称之为堆序性。因此,在一个堆中,根节点是最大(或最小)节点。如果根节点最小,称之为小顶堆(或小根堆),如果根节点最大,称之为大顶堆(或大根堆)。堆的左右孩子没有大小的顺序。
下面是一个小顶堆示例:
堆由开发人员分配和释放, 若开发人员不释放,程序结束时由 OS 回收,分配方式类似于链表。参考如下代码:
int main()
{
// C 中用 malloc() 函数申请
char* p1 = (char *)malloc(10);
cout<<(int*)p1<<endl; //输出:00000000003BA0C0
// 用 free() 函数释放
free(p1);
// C++ 中用 new 运算符申请
char* p2 = new char[10];
cout << (int*)p2 << endl; //输出:00000000003BA0C0
// 用 delete 运算符释放
delete[] p2;
}
检测数据类型的方式
- typeof
- instanceof
- Object.prototype.toString.call()
- [].constructor
1. typeof (检测基本类型值)
- 使用时直接 typeof 要检测的类型值
- typeof 可以检测number、string、boolean、null、undefined、symbol这些基本类型值
- 对于引用类型只可以检测出object(包括不同对象、数组、正则、日期等等)、function也就是说不管对象类型具体为什么类型都显示为 object
- 关于typeof的一些细节:
- 返回的结果都是字符串,还有对于null的检测结果也为object
2. instanceof (可用来检测具体对象类型,无法检测到基本类型的值)
- 使用时 [要检测的数据] instanceof [要验证的对象类型]
- 返回一个boolean数据,来判断是否属于数据该类
- 原理就是通过原型链来判断实例的__proto__是否与检测类型的prototype一致
- instanceof无法检测基本类型值,比如一个number、string等,除非是类的实例
3. 通过constructor 判断实例个类的关系
- 使用时就[要判断的类型值].constructor === [需要验证的类]
- 原理也是通过原型链,我们知道原型prototype上都有一个constructor属性指向其构造函数。所以实例获取constructor时,自身没有这个属性,向原型上找然后比对
- 无法判断基本类型值
4. 使用Object的toString方法来判断
- 使用时Object.prototype.toString.call(需要判断的值),返回的是"[object,*******]"
- 通过call来改变Object的toString方法的this指向,从而达到判断类型的效果