JavaScript入门(上)详细内容
一.JavaScript简介
1.1. 什么是JavaScript
- 官方概念:跨平台的脚本语言
- 平台:运行环境,这里一般指操作系统
- 跨平台:在各种操作系统下,都可以运行
1.2. 什么是脚本语言
- 特点:不能独立运行,依赖于网页
2.1. JS的发展历史
1995年,NetScape公司,布兰登艾奇发明了一种运行在浏览器网页里的脚本语言Livescript。
通过本地而不是服务器进行验证,为了快速的验证表单信息,这在当时来说是一个前所未有的壮举。
2.2 浏览器大战
LiveScript打开了浏览器市场,各大互联网巨头,都嗅到了蛋糕的味道,都想着分一杯羹,首当其中就是微软IE浏览器。
IE当年为了跟NetScape争夺市场份额。不甘落后很快退出适用于IE浏览器的JScript脚本语言。
由于缺乏统一标准,各个浏览器厂商发明的脚本语言,在用法和规范上不一致,成为了网页开发人员的噩梦。
1997年,ECMA(欧洲计算机制造商协会)成立了TC39委员会,委员会的成员基本都来自各大浏览器厂商。
这里面最重要的成员,就是当时如日中天的SUN公司,大家坐下来讨论之后,经过了大概1个月的世界,就快速制定出了浏览器脚本语言第一个全球标准。官方名称为ECMA Script编号ECMA-262。
由于总所周知的原因,大家没有忍住,蹭了一把JAVA热度,最终将其命名为JavaScript
至此,JavaScript诞生
如果非要说Java和Javascript有什么关系的话,就是Javascript在语法及很多API设计,内存结构设计上,直接借鉴和抄袭了Java
从这件事情可以看出,Java能这么经久不衰,是因为它非常优秀的设计(Java世界第一~
二.JavaScript-基础内容
1. 编辑工具和运行环境
- VSCode
- IE/firefox(火狐)/chrome(谷歌)/edge
2. JavaScript组成
- ECMAScript
- 版本:1,2,3,4,5,5.1,6
- DOM
- 文档对象模型(Document Object Model)
- BOM
- 浏览器对象模型(Browser Object Model)
3. script标签
所有js代码在script标签中编写
属性
- type=’text/javascript’ 声明标签内容文本格式(可省略
- src=’demo.js’ 引入外部js文件(处于引入文件功能时,Script标签内的代码将不执行)
注意:
- 可以有多个script标签,多个script标签自上而下顺序执行
3.1 script标签属性
属性 | 值 | 描述 |
---|---|---|
async | async | 规定异步执行脚本(仅适用于外部脚本)。 |
defer | defer | 规定当页面已完成解析后,执行脚本(仅适用于外部脚本)。 |
type | MIME_type | 规定脚本的 MIME 类型。 |
charset | character_set | 规定在脚本中使用的字符编码(仅适用于外部脚本)。 |
src | URL | 规定外部脚本的 URL。 |
4. 向页面输出内容
- document.write(‘内容’); 向body中添加文本
- alert(‘内容’); 弹出提示框
- console.log(‘内容’) 向控制台输出
5. JavaScript-常量和变量
5.1. 常量:值不可以改变的叫做常量
- 数据类型:
- 基本数据类型:
- 数字
- 类型:number
- 例子:100 -20 3.14
- 布尔值
- 类型:boolean
- 例子:true false
- 字符串:
- 类型:所有带单引号或双引号的
- 例子:’hello’ “hello” ‘100’ “3.14”
- 数字
- 特殊数据类型
- null 空
- undefined 未定义
- NaN(not a number 值不是数字)
- 复合/引用数据类型
- 数组
- 基本数据类型:
5.2. 变量:值可以被修改的叫做变量
- 声明变量(必须声明以后才能使用)
- 关键字(系统征用的有特殊功能的单词叫关键字):var 声明变量。
- 初始化:声明变量时,直接给这个变量赋值叫做初始化。
- 如果我们声明变量时,没有值赋给这个变量,默认值为undefined。
注意:为了提高整个程序运行的效率,我们可以将声明变量时,没有值赋值给这个变量的时候,默认值设成null,提高程序运行效率
6. 变量命名 和 弱引用
6.1. 变量命名
标识符:所有用户自定义的名字叫做标识符。
- 变量名也是标识符。
硬命名规则:
- 只能由数字、字母、下划线和美元符号($)组成
- 不能以数字开头
- 不能为保留字和关键字
- 大小写敏感
软命名规则:
见名思意(使用英文全称)
单词个数超过2个
驼峰式命名:className
下划线命名:class_name
6.2. 变量弱引用
- 在JS中变量为弱引用类型:赋值成什么数据类型就是什么类型
- 注意:不建议改变当前变量的数据类型,容易引起歧义
- typeof关键字:
- 格式: typeof 常量/变量
- 功能:输出当前常量或变量的数据类型。
7. 运算符
- 算术运算
+ - * / %(取余)
- 关系运算符
> < >= <= == != === !==
- 逻辑运算符
&& || !
- 一元运算符
++ --
- 赋值运算符
- 基本赋值运算符 =
- 复合赋值运算符 += -= /= …
7.1. 关系运算符
- 两个单个字符比较:直接比较ASCII值。
- 两个多个字符比较:逐位比较ASCII值,一旦得出大于或小于的结果停止后面的比较得出结果。
- 其中一个是数值:另一个转换为数值,再进行比较。
- 其中一个是NaN:==返回false,!=返回true;并且NaN和自身不等。
- ===恒等,相比==数据类型也加入判断条件
特殊值:
关系式 | 值 |
---|---|
null==undefined | true |
‘NaN’==NaN | false |
5==NaN | false |
NaN==NaN | false |
false==0 | true |
true==1 | true |
true==2 | false |
undefined==0 | false |
null==0 | false |
‘100’==100 | true |
‘100’===100 | false |
7.2. 逻辑运算符
与运算短路操作:当表达式1为false的时候,表达式2就不执行,直接得出结果为false。
或运算短路操作:
7.3. 自动数据类型转换
- 不同数据类型之间无法进行计算,将数据转成同一数据类型,再进行计算。
- 任何类型的数据和字符串类型的数据相加时,其他数据类型会自动转换为字符串类型。此时相加表示“拼接“的意思
- 如果字符串是一个纯数字字符组成的字符串,转成对应的数字
- 如果字符串中含有除数字以外的字符,转成NaN,NaN和任何数据运算结果都为NaN。
- 除字符串以外的数据,在进行运算时,先转成数字,再进行运算。
- true→1 , false→0 , null→0 , undefined→NaN
7.4. 强制数据类型转换:
Boolean() 其他数据类型强制转成布尔值
- 数字:非0即真
- 字符串:非空即真
Number() 其他数据类型转数字
- 只有纯数字字符字符串转成数字,其他为NaN
parseInt()取整
1.取整
1
2
3
4parseInt("25a")//25
parseInt("2a5a")//2
parseInt("a25a")//NaN
parseInt("3.14)//32.将别的进制转成十进制 必须传入字符串
1
2var str1="110100"
alert(parseInt(str1,2))//52
parseFloat() 取浮点数
举例
1
2
3parseFloat("3.14b")//3.14
parseFloat("3.1b4b")//3.1
parseFloat("a3.1b4b")//NaN
8. 流程语句练习,输出当前年的第多少天
1 | var year = 2000; |
三. JavaScript-函数
1. 函数的概念及作用
- 概念:函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
- 作用:
- 使程序变得简短而清晰
- 有利于程序维护
- 可以提高程序开发效率
- 提高了代码重用性(复用性)
2. 函数的声明与调用
1 | //无参无返回值 |
注意:见名思意,函数名必须体现其功能。
3. 封装函数
- 分析不确定值
- 将不确定值声明为形参
- 函数名与形参名都要见名思意
1 | //编写一个函数 计算两数加减乘除 使用传参 |
4. arguments
- 每一个函数内都有一个系统内置的arguments
- 作用:存储实际传入的参数
- 属性:
- arguments.length 输出当前存储参数个数
- arguments[下标] 访问其中的数据
- 注意:由于违反了见名思意原则,尽量使用形参,除非特殊情况。
5. 函数作用域
任何程序在执行的时候都要占用内存空间。函数调用的时候也要占用内存空间。
垃圾回收机制:调用函数时,系统会分配对应的空间给这个函数使用(空间大小一般情况由这个函数里声明的变量和形参决定)。当函数使用完毕之后,这个内存空间要释放,还给系统。
注意:在函数内部声明的变量和形参是属于当前函数的内存空间里的。
内存管理机制:在函数中声明的变量和形参,会随着函数的调用被创建,随着函数的调用结束而被销毁。在函数中声明的变量和形参,有效范围是当前函数(当前函数的大括号),这个范围被称为局部作用域。
就近原则:离哪个作用域近,就使用哪个作用域内的同名变量。
1 | //举例 |
6. 递归函数
满足以下三个特点就是递归:
函数自己调用自己
一般情况下有参数
一般情况下有return
作用:递归可以解决循环能做的所有事情,有一些循环不容易解决的事情,递归也能轻松解决。
递归编写方法:
- 首先找临界值,即无需计算,获得的值。
- 找这一次和上一次的关系。
- 假设当前函数已经可以试用,调用自身计算上一次
1 | //计算1~n的和 |
注意:一般公司明文禁止使用递归。(一旦出现故障瞬间开出一堆内存空间)
6.1. 递归练习
练习1:
斐波那契数列,兔子繁衍问题,设有一对新生兔子,从第四个月开始他们每个月月初都生一对兔子,新生的兔子从第四个月月初开始又每个月生一对兔子,按此规律,并假定兔子没有死亡,n(n<=20)个月月末共有多少对兔子?
一月兔 | 二月兔 | 三月兔 | 四月兔 | 总数 | |
---|---|---|---|---|---|
一月 | 1 | 0 | 0 | 0 | 1 |
二月 | 0 | 1 | 0 | 0 | 1 |
三月 | 0 | 0 | 1 | 0 | 1 |
四月 | 1 | 0 | 0 | 1 | 2 |
五月 | 1 | 1 | 0 | 1 | 3 |
六月 | 1 | 1 | 1 | 1 | 4 |
七月 | 2 | 1 | 1 | 2 | 6 |
八月 | 3 | 2 | 1 | 3 | 9 |
九月 | 4 | 3 | 2 | 4 | 13 |
1 | //1. 首先找临界值,即无需计算,获得的值。 |
练习2:
有一堆桃子不知数目,猴子第一天吃掉一半,觉得不过瘾,又多吃了一只,第二天照此办法,吃掉剩下桃子的一半另加一只,天天如此,到第num(num<=10)天早上,猴子发现只剩一只桃子了,问这堆桃子原来有多少只?(思路:n为还剩n天吃完的桃子数)
1 | peach(10)/2 - 1 = peach(9); |
练习3:
输入一个n,打印n个hello world的运行结果,
1 | //print(n) =print(n - 1) + 一次输出 |
四. JavaScript-数组
1.认识数组
1.1. 为什么要使用数组
当我们需要表示一组数据,或者叫做一次性定义很多相似的数字或变量时,就需要使用数组,如:表示一个班级学生的成绩,一年十二个月的销售数据等等
1.2. 数组的概念
- 概念:数组的字面意思就是一组数据,一组(一般情况下相同类型)的数据(不一定都是数字,可以是任意数据类型)。数组是一种数据类型。
- 数组的作用:使用单独的变量名来存储一系列的值
2.声明数组
1 | // 1.通过new创建数组 |
注意:使用1、2方法时,传入参数只有一个,并且为数字的时候,直接声明这么长的一个数组(数字为数组的长度)。
3.数组属性
- 数组.length 返回值为数组元素的个数(数组长度)。
- 元素:数组存储的每一个数据,叫做数组的元素
- 访问数组的元素:
- 数组[下标]; 下标从0开始
4.数组遍历
4.1. 随机数
1 | Math.random() //随机生成[0,1)中的数 |
4.2. 循环赋值
1 | //给数组每个元素赋值随机数 |
4.3. 快速遍历/快速枚举
差别:不用判断数组长度,运行过程中数组长度改变会出错(一般不写奇奇怪怪的代码不会发生错误)。
1 | var arr = [10,20,30,40,50]; |
5.数组方法
5.1. 栈结构
- 栈:木盆
- 放的时候最先放的放最底下,拿的时候拿最后放下去的。
- 特点:先进的后出
- 数组的两个方法形成栈结构:
- push 方法
- 格式:数组.push(参数1,参数2…);
- 功能:给数组的末尾添加元素。
- 返回值:添加完元素后数组的长度
- pop 方法
- 格式:数组.pop();
- 参数:没有参数
- 返回值:取下的元素
- 功能:从数组末尾取下一个元素
- push 方法
5.1. 队列结构
- 结构:从末尾进,从头部出。
- 特点:先进的先出
- shift() 方法
- 格式:数组.shift();
- 参数:没有参数
- 功能:从数组的头部取下一个元素
- 返回值:取下的元素
- unshift() 方法
- 格式:数组.unshift(参数1,参数2…)
- 功能:从数组的头部插入元素
- 返回值:插完元素以后数组的长度
5.2. concat()方法
- 拷贝原数组,生成新数组。
- 合并数组
- 格式:数组.concat(数组,数据,…)
- 返回值:合并成的新数组。
- 注意:就算传入是数组,数组中元素中的元素要单独拆出来再进行合并。
5.2. slice()方法
- 格式:数组.slice(start,end); [start,end)
- 功能:可以基于当前数组获取指定区域元素[start,end),提取出元素生成新数组。
- 返回值:生成的新数组,原数组不会发生任何的改变。
5.3. splice()方法
格式:数组.splice(start,length,数据1,数据2…)
- 参数:
- start 开始截取的位置
- length 截取元素的长度
- 第三个参数开始:在start位置插入的元素
- 返回值:截取下来的元素组成的数组
- 参数:
增加
1
2
3
4var arr = [10,20,30,40,50];
var res = arr.splice(2,0,"hello","world");
alert(arr);//10,20,hello,world,30,40,50
alert(res);//空数组删除
1
2
3
4var arr = [10,20,30,40,50];
var res = arr.splice(1,2);
alert(arr);//10,40,50
alert(res);//20,30修改(先删后增)
1
2
3var arr = [10,20,30,40,50];
arr.splice(2,1,"hello");
alert(arr);//10,20,hello,40,50
5.4. join()方法
- 格式:数组.join(字符串)
- 功能:将数组中的元素,用传入的拼接符,拼接成一个字符串。
- 返回值:拼接好的字符串
1 | var arr = [10,20,30]; |
5.5. resver()方法
- 功能:逆序
1 | var arr = [true,"hello",100]; |
5.6. sort()方法
格式:数组.sort() 默认从小到大排序,按字符串排序
参数:一个函数,代表要怎么进行排序(固定用法)
按数值排序方法
1
2
3
4
5
6
7
8
9var arr=[1,10,20,30,25,5];
//从小到大
arr.sort(function(value1,value2){
return value1 - value2;
})
//从大到小
arr.sort(function(value1,value2){
return value2 - value1;
})
5.7. 数组求平均数
定义一个含有38个整型元素的数组,按顺序分别赋予从2开始的偶数;然后按顺序每五个数求出一个平均值,放在另一个数组中并输出。
1 | var arr=new Array(30); |
6. 引用数据类型
运行程序:
- 1、准备运行程序要用的空间(一旦分配好,内存大小没办法进行改变)
- 2、开始运行程序
数组的变量存储的是数组的地址值。
concat()方法:拷贝原数组生成一个新数组
7. 声明提升和省略var
1 | //声明提升 |
- 省略var声明变量
- 变量会被强制声明成全局变量
8. 二维数组
- 来源:数组中每一个元素,元素可以是任意数据类型,元素可以是数组,数组存数组是存的数组地址
- 二维数组:人为起的
1 | /* |
9. 冒泡和选择排序
冒泡排序:
- 规则:前后两个数两两进行比较,如果符合交换条件就换位
- 规律:冒泡排序每过一轮排序,都可以找出一个较大的数,放在正确的位置
1 | var arr=[9,8,4,2,4,6]; |
选择排序(打擂台):
- 规则:选出一个位置,这个位置上的数,和后面所有的数进行比较,如果比较出大小就交换位置。
- 规律:每一轮都能选出一个最小的数,放在正确位置
1 | var arr=[9,8,4,2,4,6]; |
10.数组练习
1 | //随机给出一个五位以内的数,然后输出该数共有多少位,每位分别是什么 |
1 | /* |
五. JavaScript-ECMA5
1.ECMA5严格模式
简介:除正常运行模式,ECMAscript 5 添加了第二种运行模式:“严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
目的:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。
- 消除代码运行的一些不安全之处,保证代码运行安全。
- 提高编译器效率,增加运行速度。
- 为未来新版本的Javascript做好铺垫。
格式:
1
2
3
4
5/*
严格模式:写在哪个作用内下,就在哪个作用域内生效。
"use strict";
注:尽量注意不要把严格模式写在全局。
*/
1.1.严格模式的行为变更
全局变量声明时,必须加var
1
2
3
4<script>
;
a=10;//报错,因为a没有被var声明
</script>this无法指向全局对象。
1
2
3
4
5
6
7<script>
;
function a(){
this.b=10;//报错,因为this是undefined
}
a()
</script>函数内重名属性
1
2
3
4
5
6<script>
;
function a(b,b,c){
//语法错误:上下文中不允许重复的参数名称
}
</script>arguments对象不允许被动态改变 :
1
2
3
4
5
6
7function show(num1,num2){
;
num1="hello";
alert(num1+","+num2);//hello,20
alert(arguments[0]+","+arguments[1])//10,20
}
show(10,20);新增保留字:implements,interface,let,package,private,protected,public,static,yield。
注:保留字不能声明为变量名
1
2
3
4
5
6<script>
;
function package(protected){//语法错误
var implements;//语法错误
}
</script>
2.ECMA5新增数组方法
1. indexOf()方法
格式:数组.index(item,start)
参数:
- item:任意数据
- start:下标 可以不传入,默认为0
功能:在数组中查找第一次出现item元素的下标,从start开始查找
返回值:
- -1 没有查找到
- 大于等于0
举例:
1
2
3var arr[1,2,3,4,5,6,7,2,5,6];
var index = arr.indexOf(20,2);
alert(index);
2.forEach()循环
- 数组遍历方法:
- for循环
- for…in
- forEach(ECMA5新增)
1 | var arr=[10,20,30,40,50]; |
- 彩蛋:forEach出来的时候被抵制了一段时间,理由是forEach 屏蔽了初学者对于循环的理解。
3.map()方法
- 映射:根据固定的运算公式把原来的数经过公式算出结果放在对应下标里
1 | var arr=[10,20,30,40,50]; |
4.filter()过滤
1 | var arr=[5,1,2,3,4,5] |
5.some()方法
- 功能:在数组中查找是否有符合条件的元素,有返回true,没有返回false。
- 短路操作:只要找到符合条件的元素,后面的循环就停止了。
1 | var arr=[10,20,30,40,50]; |
6.every()方法
- 功能:在数组中查找是否每一个元素都符合条件,有返回true,没有返回false。
- 短路操作:只要找到不符合条件的元素,后面循环停止。
1 | var arr=[10,20,30,40,50]; |
7.reduce()归并
- 归并:先把前两个数并一块,然后再并第二个第三个
1 | var arr=[10,20,30,40,50]; |
六. JavaScript-字符串
1.字符串的基本概念
字符串概念:所有带单引号或双引号的都叫字符串
字符串的声明:
- 通过new运算符去声明字符串
- 省略new声明字符串
- 字符串常量复制
1 | var str =new String(100); |
- 访问字符串中的字符的个数:
- 字符串.length 访问字符串中字符的个数
- 注:中文字符集,utf-8(三个字符表示一个汉字) gbk(两个字符表示一个汉字) 在计数的时候都是当作一个汉字计数
- 访问字符串中单个字符:
- 字符串.charAt(下标) 从0开始
- 字符串[下标]
- 注意:字符串只读,一旦被声明没办法修改,如果非要修改,只能将原字符串销毁再生成
- 注意:在JS中,字符串既是基本数据类型也是符合数据类型。
- 字符串遍历:
- for循环
2.字符串方法
1.不常用字符串方法格式:字符串.函数名()
1 | big() 大好字体显示字符串 |
2.字符串获取方法
1 | charAt(3) //获取下标为3的字符 |
3.字符串查找方法
1 | /* |
4.字符串提取方法
1 | /* |
5.字符串替换分割
1 | /* |
6.字符串转大小写
1 | /* |
3.字符串练习
1 | //1、将字符串str="When I was young,I love a girl in neighbor class."中,从young提取到girl生成新字符串 |
4.字符串验证码生成
1 | //纯数字验证码 |