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组成

  1. ECMAScript
    • 版本:1,2,3,4,5,5.1,6
  2. DOM
    • 文档对象模型(Document Object Model)
  3. 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. 向页面输出内容

  1. document.write(‘内容’); 向body中添加文本
  2. alert(‘内容’); 弹出提示框
  3. 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. 变量:值可以被修改的叫做变量

  1. 声明变量(必须声明以后才能使用)
    • 关键字(系统征用的有特殊功能的单词叫关键字):var 声明变量。
  2. 初始化:声明变量时,直接给这个变量赋值叫做初始化。
  3. 如果我们声明变量时,没有值赋给这个变量,默认值为undefined。

注意:为了提高整个程序运行的效率,我们可以将声明变量时,没有值赋值给这个变量的时候,默认值设成null,提高程序运行效率

6. 变量命名 和 弱引用

6.1. 变量命名

  • 标识符:所有用户自定义的名字叫做标识符。

    • 变量名也是标识符。
  • 硬命名规则:

    1. 只能由数字、字母、下划线和美元符号($)组成
    2. 不能以数字开头
    3. 不能为保留字和关键字
    4. 大小写敏感
  • 软命名规则:

    1. 见名思意(使用英文全称)

    2. 单词个数超过2个

      • 驼峰式命名:className

      • 下划线命名:class_name

6.2. 变量弱引用

  • 在JS中变量为弱引用类型:赋值成什么数据类型就是什么类型
  • 注意:不建议改变当前变量的数据类型,容易引起歧义
  • typeof关键字:
    • 格式: typeof 常量/变量
    • 功能:输出当前常量或变量的数据类型。

7. 运算符

  1. 算术运算
    • + - * / %(取余)
  2. 关系运算符
    • > < >= <= == != === !==
  3. 逻辑运算符
    • && || !
  4. 一元运算符
    • ++ --
  5. 赋值运算符
    • 基本赋值运算符 =
    • 复合赋值运算符 += -= /= …

7.1. 关系运算符

  1. 两个单个字符比较:直接比较ASCII值。
  2. 两个多个字符比较:逐位比较ASCII值,一旦得出大于或小于的结果停止后面的比较得出结果。
  3. 其中一个是数值:另一个转换为数值,再进行比较。
  4. 其中一个是NaN:==返回false,!=返回true;并且NaN和自身不等。
  5. ===恒等,相比==数据类型也加入判断条件

特殊值:

关系式
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
      4
      parseInt("25a")//25
      parseInt("2a5a")//2
      parseInt("a25a")//NaN
      parseInt("3.14)//3
    • 2.将别的进制转成十进制 必须传入字符串

      1
      2
      var str1="110100"
      alert(parseInt(str1,2))//52
  • parseFloat() 取浮点数

    • 举例

      1
      2
      3
      parseFloat("3.14b")//3.14
      parseFloat("3.1b4b")//3.1
      parseFloat("a3.1b4b")//NaN

8. 流程语句练习,输出当前年的第多少天

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var year = 2000;
var month = 1;
var date = 15;
var sum = 0;
switch(month){
case 12:
sum += 30;
case 11:
sum += 31;
case 10:
sum += 30;
case 9:
sum += 31;
case 8:
sum += 31;
case 7:
sum += 30;
case 6:
sum += 31;
case 5:
sum += 30;
case 4:
sum += 31;
case 3:
sum += 28;
if(uear % 4==0 && year %100 !=0 ||year % 400==0){
sum += 1;
}
case 2:
sum += 31;
case 1:
sum += date;
break;
default:
alert("error")
break;
}
alert("这是第"+sum+"天");
var week = Math.ceil(sum/7);
alert("这是第"+week+"周");

三. JavaScript-函数

1. 函数的概念及作用

  • 概念:函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
  • 作用:
    • 使程序变得简短而清晰
    • 有利于程序维护
    • 可以提高程序开发效率
    • 提高了代码重用性(复用性)

2. 函数的声明与调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//无参无返回值
function 函数名(){
函数体;
}
//调用
函数名();

//有参无返回值
function 函数名(形参1,形参2...){
函数体;
}
//调用
函数名(实参1,实参2...)

//有参数有返回值
function 函数名(形参1,形参2...){
函数体;
return 表达式;
//函数调用的结果为表达式的值
//函数遇到return会中止
}

注意:见名思意,函数名必须体现其功能。

3. 封装函数

  1. 分析不确定值
  2. 将不确定值声明为形参
  3. 函数名与形参名都要见名思意
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//编写一个函数 计算两数加减乘除 使用传参
function operation(num1,operator,num2){
switch(operator){
case "+":
return num1 + num2;
break;
case "-":
return num1 - num2;
break;
case "*":
return num1 * num2;
break;
case "/":
return num1 / num2;
break;
default:
alert("error");
break;
}
}

//输入n为偶数 1/2+1/4+...+1/n,奇数,1/1+1/3+...+1/n
function sum(n){
var res=0;
if(n % 2==0){
for(var i = 2 ; i <= n; i += 2){
res += 1/i;
}else{
for(var i = 1;i <= n; i += 2){
res += 1/i;
}
}
return res;
}

4. arguments

  • 每一个函数内都有一个系统内置的arguments
  • 作用:存储实际传入的参数
  • 属性:
    • arguments.length 输出当前存储参数个数
    • arguments[下标] 访问其中的数据
  • 注意:由于违反了见名思意原则,尽量使用形参,除非特殊情况。

5. 函数作用域

任何程序在执行的时候都要占用内存空间。函数调用的时候也要占用内存空间。

垃圾回收机制:调用函数时,系统会分配对应的空间给这个函数使用(空间大小一般情况由这个函数里声明的变量和形参决定)。当函数使用完毕之后,这个内存空间要释放,还给系统。

注意:在函数内部声明的变量和形参是属于当前函数的内存空间里的。

内存管理机制:在函数中声明的变量和形参,会随着函数的调用被创建,随着函数的调用结束而被销毁。在函数中声明的变量和形参,有效范围是当前函数(当前函数的大括号),这个范围被称为局部作用域。

就近原则:离哪个作用域近,就使用哪个作用域内的同名变量。

1
2
3
4
5
6
7
8
9
//举例
var a = 10,b=20;
function show(a){
var b = 100;
a += 5;
alert(a + "," + b);
}
show(a);//15,100
alert(a + ","+ b)//10,20

6. 递归函数

满足以下三个特点就是递归:

  1. 函数自己调用自己

  2. 一般情况下有参数

  3. 一般情况下有return

作用:递归可以解决循环能做的所有事情,有一些循环不容易解决的事情,递归也能轻松解决。

递归编写方法:

  1. 首先找临界值,即无需计算,获得的值。
  2. 找这一次和上一次的关系。
  3. 假设当前函数已经可以试用,调用自身计算上一次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//计算1~n的和
function sum(n){
var res=0;
for(var i = 1; i<=n; i++){
res += i;
}
return res;
}
alert(sun(100));//5050

//递归写法
//sum(100)=sum(99)+100;
//sum(n)=sun(n-1)+n
function sum2(n){
if(n==1){
return 1;
}
return sum(n-1)+n;
}

alert(sum(100));//5050

注意:一般公司明文禁止使用递归。(一旦出现故障瞬间开出一堆内存空间)

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
2
3
4
5
6
7
8
9
10
11
//1. 首先找临界值,即无需计算,获得的值。
//2. 找这一次和上一次的关系。
//3. 假设当前函数已经可以试用,调用自身计算上一次
//rabbit(4) = rabbit(3) + rabbit(1);
//rabbit(n) = rabbit(n-1) + rabbit(n - 3)
function rabbit(n){
if(n<4){
return 1;
}
return rabbit(n-1) + rabbit(n - 3)
}

练习2:

有一堆桃子不知数目,猴子第一天吃掉一半,觉得不过瘾,又多吃了一只,第二天照此办法,吃掉剩下桃子的一半另加一只,天天如此,到第num(num<=10)天早上,猴子发现只剩一只桃子了,问这堆桃子原来有多少只?(思路:n为还剩n天吃完的桃子数)

1
2
3
4
5
6
7
8
9
peach(10)/2 - 1 = peach(9);
peach(10) = (peach(9) + 1) * 2;
peach(n) = (peach(n-1) + 1) * 2;
function peach(n){
if(n == 1){
return 1;
}
return(peach(n-1) + 1) * 2;
}

练习3:

输入一个n,打印n个hello world的运行结果,

1
2
3
4
5
6
7
8
//print(n) =print(n - 1) + 一次输出
function print(n){
if(n == 0){
return;
}
document.write("hello world<br/>");
return print(n - 1);
}

四. JavaScript-数组

1.认识数组

1.1. 为什么要使用数组

​ 当我们需要表示一组数据,或者叫做一次性定义很多相似的数字或变量时,就需要使用数组,如:表示一个班级学生的成绩,一年十二个月的销售数据等等

1.2. 数组的概念

  • 概念:数组的字面意思就是一组数据,一组(一般情况下相同类型)的数据(不一定都是数字,可以是任意数据类型)。数组是一种数据类型。
  • 数组的作用:使用单独的变量名来存储一系列的值

2.声明数组

1
2
3
4
5
6
7
8
9
// 1.通过new创建数组
// 参数:传入任意的数据,存储到数组中
var arr = new Array(100,true,"hello");

// 2.省略new运算符创建数组
var arr = Array(100,true,"hello");

// 3.数组常量进行赋值。(JS一般使用中括号[])
var arr = [100,true,"hello"];

注意:使用1、2方法时,传入参数只有一个,并且为数字的时候,直接声明这么长的一个数组(数字为数组的长度)。

3.数组属性

  • 数组.length 返回值为数组元素的个数(数组长度)。
    • 元素:数组存储的每一个数据,叫做数组的元素
  • 访问数组的元素:
    • 数组[下标]; 下标从0开始

4.数组遍历

4.1. 随机数

1
2
Math.random() //随机生成[0,1)中的数
paerseInt(Math.random()*10) //随机生成0~9的整数

4.2. 循环赋值

1
2
3
4
5
//给数组每个元素赋值随机数
var arr = new Array(10);
for(var i = 0; i < arr.length; i++){
arr[i] = paerseInt(Math.random()*10);
}

4.3. 快速遍历/快速枚举

差别:不用判断数组长度,运行过程中数组长度改变会出错(一般不写奇奇怪怪的代码不会发生错误)。

1
2
3
4
5
var arr = [10,20,30,40,50];
//页面上分别将每一个数输出
for(var i in arr){
document.write(arr[i]+"<br/>");
}

5.数组方法

5.1. 栈结构

  • 栈:木盆
    • 放的时候最先放的放最底下,拿的时候拿最后放下去的。
    • 特点:先进的后出
  • 数组的两个方法形成栈结构:
    • push 方法
      • 格式:数组.push(参数1,参数2…);
      • 功能:给数组的末尾添加元素。
      • 返回值:添加完元素后数组的长度
    • pop 方法
      • 格式:数组.pop();
      • 参数:没有参数
      • 返回值:取下的元素
      • 功能:从数组末尾取下一个元素

5.1. 队列结构

  • 结构:从末尾进,从头部出。
  • 特点:先进的先出
  • shift() 方法
    • 格式:数组.shift();
    • 参数:没有参数
    • 功能:从数组的头部取下一个元素
    • 返回值:取下的元素
  • unshift() 方法
    • 格式:数组.unshift(参数1,参数2…)
    • 功能:从数组的头部插入元素
    • 返回值:插完元素以后数组的长度

5.2. concat()方法

  1. 拷贝原数组,生成新数组。
  2. 合并数组
    • 格式:数组.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
    4
    var 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
    4
    var arr = [10,20,30,40,50];
    var res = arr.splice(1,2);
    alert(arr);//10,40,50
    alert(res);//20,30
  • 修改(先删后增)

    1
    2
    3
    var arr = [10,20,30,40,50];
    arr.splice(2,1,"hello");
    alert(arr);//10,20,hello,40,50

5.4. join()方法

  • 格式:数组.join(字符串)
  • 功能:将数组中的元素,用传入的拼接符,拼接成一个字符串。
  • 返回值:拼接好的字符串
1
2
3
4
var arr = [10,20,30];
var str = arr.join("==");
alert(str);10==20==30
alert(arr);10,20,30

5.5. resver()方法

  • 功能:逆序
1
2
3
var arr = [true,"hello",100];
arr.reverse();
alert(arr);//100,hello,true

5.6. sort()方法

  • 格式:数组.sort() 默认从小到大排序,按字符串排序

  • 参数:一个函数,代表要怎么进行排序(固定用法)

  • 按数值排序方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arr=new Array(30);
for(var i=0;i<arr.length;i++){
arr[i]=i*i+2;
}
var avgArr=[];
for(var i=0;i<6;i++){
var newArr.splice(0,5);//splice对原数组进行修改
//var newArr = arr.slice(i*5,(i+1)*5);也行
var sum=0;
for(var j=0;j<newArr.length;j++){
sum+=newArr[j];
}
avgArr.push(sum/5);
}
alert(avgArr);

6. 引用数据类型

  • 运行程序:

    • 1、准备运行程序要用的空间(一旦分配好,内存大小没办法进行改变)
    • 2、开始运行程序
  • 数组的变量存储的是数组的地址值。

  • concat()方法:拷贝原数组生成一个新数组

7. 声明提升和省略var

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//声明提升
alert(num);
var num=10;
alert(num);
//undefined 10

/*
内存分配,一次分配
预编译:所有代码运行之前,计算机将代码从头到尾看一遍。
将这个程序需要运行的空间一次性分配好。
var num=10在第二行 声明var num在所有程序之前
相当于:*/
var num;
alert(num);
num=10;
alert(num);
//函数也会声明提升,预编译时会将函数提到代码最前面

//总结:在当前作用域,声明变量和函数,会直接提升在整个代码的最前面运行
  • 省略var声明变量
    • 变量会被强制声明成全局变量

8. 二维数组

  • 来源:数组中每一个元素,元素可以是任意数据类型,元素可以是数组,数组存数组是存的数组地址
  • 二维数组:人为起的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
通过循环按顺序为一个5x5的二维数组a赋1到25的自然数,然后输出该数组的左下半三角
*/
var arr = {
[1,2,3,4,5],
[6,7,8,9,10],
[11,12,13,14,15],
[16,17,18,19,20],
[21,22,23,24,25]
};
//打印靠左三角形图案
for(var i=0;i<5;i++){
for(var j=0;j<=i;j++){
document.write("o")
}
document.write("<br/>")
}
//结合一下
for(var i=0;i<arr.length;i++){
for(var j=0;j<=i;j++){
document.write(arr[i][j]+" ")
}
document.write("<br/>")
}

9. 冒泡和选择排序

冒泡排序:

  • 规则:前后两个数两两进行比较,如果符合交换条件就换位
  • 规律:冒泡排序每过一轮排序,都可以找出一个较大的数,放在正确的位置
1
2
3
4
5
6
7
8
9
10
11
12
var arr=[9,8,4,2,4,6];
for(var i=0;i<arr.length-1;i++){
//每一轮比较的次数
for(var j=0;j<arr.length-(i+1);j++){
if(arr[j]>arr[j+1]){
//交换位置
var tmp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}

选择排序(打擂台):

  • 规则:选出一个位置,这个位置上的数,和后面所有的数进行比较,如果比较出大小就交换位置。
  • 规律:每一轮都能选出一个最小的数,放在正确位置
1
2
3
4
5
6
7
8
9
10
var arr=[9,8,4,2,4,6];
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
var tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
}

10.数组练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//随机给出一个五位以内的数,然后输出该数共有多少位,每位分别是什么
function count0fNum(num){
var arr=[];
while(num){
arr.unshift(num % 10);
num = parseInt(num/10);
}
alert("一共是:"+arr.length+"位,每一位分别是"+arr)
}
//编写函数has(arr,60)判断数组中是否存在60这个元素,返回布尔类型
function has(arr,item){
for(var i=0;i<arr.length;i++){
if(arr[i]===item){
return true;
}
}
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
生成13位条形码
Ean-13码规则:第十三位数字是前十二位数字经过计算得到的校验码。
例如:690123456789
第十三位计算其验证码的过程为:
@前十二位的奇数位和6+0+2+4+6+8=26
@前十二位的偶数位和9+1+3+5+7+9=34
@将奇数和与偶数和的三倍相加26+34*3=128
@取结果的个位数:128的个位数为8
@用10减去这个个位数10-8=2
所以校验码为2(如果结果个位数为0,校验码为0)
例如:输入692223361219输出6922233612192
*/
functino ean13(num){
//1、将其中每一位数取下来
var arr=[];
while(num){
arr.unshift(num%10);
parseInt(num/10);
}
var odd=0;
var even=0;
for(var i=0;i<arr.length;i++){
if(i%2==0){
//奇数
odd += arr[i];
}else{
//偶数
even += arr[i];
}
}
var sum=(odd+even*3)%10;
if(sum){
sum=10-sum;
}
//生成第13位数
arr.push(sum);
return Number(arr.join(""));
}

五. JavaScript-ECMA5

1.ECMA5严格模式

  • 简介:除正常运行模式,ECMAscript 5 添加了第二种运行模式:“严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。

  • 目的:

    1. 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。
    2. 消除代码运行的一些不安全之处,保证代码运行安全。
    3. 提高编译器效率,增加运行速度。
    4. 为未来新版本的Javascript做好铺垫。
  • 格式:

    1
    2
    3
    4
    5
    /*
    严格模式:写在哪个作用内下,就在哪个作用域内生效。
    "use strict";
    注:尽量注意不要把严格模式写在全局。
    */

1.1.严格模式的行为变更

  1. 全局变量声明时,必须加var

    1
    2
    3
    4
    <script>
    "use strict";
    a=10;//报错,因为a没有被var声明
    </script>
  2. this无法指向全局对象。

    1
    2
    3
    4
    5
    6
    7
    <script>
    "use strict";
    function a(){
    this.b=10;//报错,因为this是undefined
    }
    a()
    </script>
  3. 函数内重名属性

    1
    2
    3
    4
    5
    6
    <script>
    "use strict";
    function a(b,b,c){
    //语法错误:上下文中不允许重复的参数名称
    }
    </script>
  4. arguments对象不允许被动态改变 :

    1
    2
    3
    4
    5
    6
    7
    function show(num1,num2){
    "use strict";
    num1="hello";
    alert(num1+","+num2);//hello,20
    alert(arguments[0]+","+arguments[1])//10,20
    }
    show(10,20);
  5. 新增保留字:implements,interface,let,package,private,protected,public,static,yield。

    注:保留字不能声明为变量名

    1
    2
    3
    4
    5
    6
    <script>
    "use strict";
    function package(protected){//语法错误
    var implements;//语法错误
    }
    </script>

2.ECMA5新增数组方法

1. indexOf()方法

  • 格式:数组.index(item,start)

  • 参数:

    • item:任意数据
    • start:下标 可以不传入,默认为0
  • 功能:在数组中查找第一次出现item元素的下标,从start开始查找

  • 返回值:

    • -1 没有查找到
    • 大于等于0
  • 举例:

    1
    2
    3
    var 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
2
3
4
5
6
7
8
var arr=[10,20,30,40,50];
arr.forEach(function(item,index,arr){
/*
item当前遍历到的元素
index当前遍历到元素的下标
arr数组本身
*/
});
  • 彩蛋:forEach出来的时候被抵制了一段时间,理由是forEach 屏蔽了初学者对于循环的理解。

3.map()方法

  • 映射:根据固定的运算公式把原来的数经过公式算出结果放在对应下标里
1
2
3
4
5
6
7
var arr=[10,20,30,40,50];
var newArr=arr.map(function(item,index,arr){
//遍历要做的事情
return item*1.3;
});
alert(newArr)//;12,26,39,52,65
alert(arr);//10,20,30,40,50

4.filter()过滤

1
2
3
4
var arr=[5,1,2,3,4,5]
var newArr=arr.filter(function(item,index,arr){
return item>2;//找出所有大于2的元素
});//结果:[5,3,4,5],不改变原数组新生成数组

5.some()方法

  • 功能:在数组中查找是否有符合条件的元素,有返回true,没有返回false。
  • 短路操作:只要找到符合条件的元素,后面的循环就停止了。
1
2
3
4
5
var arr=[10,20,30,40,50];
var newArr=arr.some(function(item,index,arr){
//遍历要做的事情
return item>20;
});

6.every()方法

  • 功能:在数组中查找是否每一个元素都符合条件,有返回true,没有返回false。
  • 短路操作:只要找到不符合条件的元素,后面循环停止。
1
2
3
4
var arr=[10,20,30,40,50];
var newArr=arr.every(function(item,index,arr){
return item>20;
});

7.reduce()归并

  • 归并:先把前两个数并一块,然后再并第二个第三个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var arr=[10,20,30,40,50];
var newArr=arr.reduce(function(prev,next,index,arr){
/*
prev 第一次 下标为0的元素
第二次开始 上一次遍历return的值

next 从下标1开始,当前遍历到的元素
arr数组本身
*/
alert(prev+","+next);
return prev + next;
});
alert(newArr)
/*
10,20
30,30
60,40
100,50
150
*/

六. JavaScript-字符串

1.字符串的基本概念

  • 字符串概念:所有带单引号或双引号的都叫字符串

  • 字符串的声明:

    • 通过new运算符去声明字符串
    • 省略new声明字符串
    • 字符串常量复制
1
2
3
4
5
6
var str =new String(100);
alert(typeof str);//object
var str1 = String(100);
alert(typeof str1);//string
var str2 = "100";
alert(typeof str2);//string
  • 访问字符串中的字符的个数:
    • 字符串.length 访问字符串中字符的个数
    • 注:中文字符集,utf-8(三个字符表示一个汉字) gbk(两个字符表示一个汉字) 在计数的时候都是当作一个汉字计数
  • 访问字符串中单个字符:
    • 字符串.charAt(下标) 从0开始
    • 字符串[下标]
  • 注意:字符串只读,一旦被声明没办法修改,如果非要修改,只能将原字符串销毁再生成
  • 注意:在JS中,字符串既是基本数据类型也是符合数据类型。
  • 字符串遍历:
    • for循环

2.字符串方法

1.不常用字符串方法格式:字符串.函数名()

1
2
3
4
5
6
7
8
9
10
11
big()		大好字体显示字符串
blink() 显示闪动字符串(ie无效)
bold() 粗体显示字符串
fixed() 以打字机文本显示字符串
strike() 使用删除线来显示字符串
fontcolor() 指定颜色显示字符串
fontsize() 指定尺寸显示字符串
link() 字符串显示为链接
sub() 字符串显示为下标
sup() 字符串显示为上标
//document.write()中使用,用特殊样式输出字符串

2.字符串获取方法

1
2
3
4
5
6
7
charAt(3) //获取下标为3的字符
charCodeAt(3) //获取下标为3的字符的编码
//上面2个方法使用字符串对象调用

fromCharCode(94) //编码转换成字符串
//该方法是String静态方法,所以用String调用,
如:var str = String.fromCharCode(98,99);

3.字符串查找方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
indexOf()
格式:supStr.indexOf(subStr,start);
参数:第一个,要查的字符串
start 从哪个下标开始 默认为0
功能:在supStr中查找subStr第一次出现的位置,从start这个位置开始查找。
返回值:-1 没有找到
*/
var supStr="abcabcabc";
var subStr="abc";
var index = supStr.indexOf(subStr);//0
var index = supStr.indexOf(subStr,1);//3
var index = supStr.indexOf(subStr,4);//6
//======================================================
/*
lastIndexOf()
格式:supStr.lastIndexOf(subStr);
功能:在supStr中查找subStr最后一次出现的位置
参数:第二个参数是开始查找的索引位置,查找方向是从右往左
返回值:-1 没有找到
*/
var supStr="abcabcabc";
var subStr="abc";
var index = supStr.lastIndexOf(subStr);//6
var index = supStr.lastIndexOf(subStr)

var arr=[10,5,2,3,4,5,7,8,9];
//索引值:0 1 2 3 4 5 6 7 8
console.log(arr.lastIndexOf(4));//4
console.log(arr.lastIndexOf(7));//6
console.log(arr.lastIndexOf(5));//5
/*
//======================================================
search()
格式:supStr.search(subStr);
参数:字符串/正则表达式
功能:在supStr中查找subStr第一次出现的位置
返回值:-1 没有查找到
*/
var supStr="Abcabcabc";
var subStr="/abc/i";
var index = supStr.search(subStr);//0

4.字符串提取方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
substring
格式:字符串.substring(start,end);
功能:将字符串中[start,end)提取这部分字符,生成新字符串
返回值:新字符串
*/
var str = "hello";
var newStr=str.substring(1,4);
alert(newStr);//ell
alert(str);//hello
//======================================================
/*
substr
格式:字符串.substr(start,length);
返回值:新字符串
*/
var str="hello";
var newStr = str.substr(1,3);
alert(newStr);//ell
alert(str)//hello
//======================================================
/*
slice(数组方法)
格式:字符串.slice(start,end);
*/
var newStr=str.slice(1,4);
alert(newStr);//ell
alert(str);//hello

5.字符串替换分割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
replace() 字符串替换
格式:supStr.replace(oldStr,newStr);
功能:用newStr将oldStr,替换,生成新字符串。
参数:
第一个参数传入的是字符串只能替换一次。
第一个参数可以传入正则表达式
返回值:新生成的字符串。
*/
var str="how are are you";
var newStr = str.replace("are","old are")
var newStr2 = str.replace("/are/g","old are")
alert(newStr);//how old are are you
alert(str);//how are are you
alert(newStr2);//how old are old are you
//======================================================
/*
split() 字符串分割
格式:字符串.split(分隔符,length)
参数:
第一个参数,用这个分隔符对字符串进行分割
第二个参数,控制返回的数组的元素格式,一般不用
功能:用分隔符对原字符串分割分割玩的字串放在数组中返回
返回值:数组
*/
var str="how are are you";
var newStr = str.split(" s")
alert(newStr);//how,are,you
alert(str);//how are you

/*
注意:1.相邻两个分隔符,会产生空字符串。
2.分割符是空字符串"",直接将每一个字符单独分割成字串,放在数组中返回。
*/

6.字符串转大小写

1
2
3
4
5
/*
toLowerCase() 转成全小写
toUpperCase() 转成全大写
注:生成新字符串
*/

3.字符串练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//1、将字符串str="When I was young,I love a girl in neighbor class."中,从young提取到girl生成新字符串
var str="When I was young,I love a girl in neighbor class."
var start = str.indexOf("young");
var end=str.indexOf("girl")+"girl".length;
var newStr = str.substring(start,end);
alert(newStr);

/*
2、将字符中单词用空格隔开,已知传入的字符串只有字母,每个单词首字母大写,把每个单词用空格隔开,值保留第一个单词首字母大写
传入:"HelloMyWorld"
返回:"Hello my world"

思路
1、字符串转数组 split("")
2、数组转字符串 join("")
*/
function wordOfStr(str){
var arr=str.split("");
for(var i = 1;i<arr.length;i++){
if(arr[i]>="A"&&arr[i]<="Z"){
//大写转小写,插空格
arr[i]=arr[i].toLowerCase();
arr.splice(i,0," ");
}
}
return arr.join("");
}
wordOfStr("HelloMyWorld");

/*
3.将字符串安单词进行排序,空格作为划分单词的唯一条件
传入"Welcome to Beijing"
改为"Beijing to Welcome"
*/

function reverseStr(str){
var arr=arr.split(" ");
}

4.字符串验证码生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//纯数字验证码
function numTestCode(n){
var arr=[];
for(var i=0;i<n;i++){
var num=parseInt(Math.random()*10);
arr.push(num);
}
return arr.join("");
}
//字母数字验证码
/*
0-9
a-z 97-122
A-Z 65-90
随机ASCII码值
*/
function testCode(n){
var arr=[];
for(var i=0;i<n;i++){
var num=parseInt(Math.random()*123);
if(num>=0&&num<=9){
arr.push(num);
}else if(num>=97&&num<=122||num>=65&&<=90){
arr.push(String.fromCharCode(num));
}else{
i--;
}
}
return arr.join("");
}

评论