目录
一、计算机编程基础导读
1 编程语言
2 计算机基础
二、初识JavaScript
1 JavaScript历史
2 JavaScript是什么
3 JavaScript的作用
4 浏览器执行JS过程
5 JS的组成
6 JS三种书写位置
7 JS中的注释
8 JavaScript输入输出语句
三、变量导读
1 变量概述
2 变量的使用
3 变量语法的扩展
3.1 一个变量被重新赋值
3.2 声明多个变量
3.3 声明变量的特殊情况
3.4 变量的命名规范
四、数据类型导读
1 数据类型简介
1.1 为什么需要数据类型?
1.2 变量的数据类型
2 数据类型的分类
2.1 简单数据类型(Number,String,Boolean,Undefined,Null)
2.2 复杂数据类型(object)2.3 typeof 检测数据类型
3 数据类型转换
3.1 把其他类型转换为字符串类型
3.2 把其他类型转换为数字型
3.3 把其他类型转换为布尔型
4 标识符、关键字、保留字
4.1 标识符
4.2 关键字
4.3 保留字
五、JavaScript运算符导读
1 算术运算符 + - * / % 加减乘除取余
2 表达式和返回值
3 递增递减运算符 ++ --
3.1 前置递增运算符
3.2 后置递增运算符
4 比较运算符
5 逻辑运算符
5.1 逻辑中断逻辑与
5.2 逻辑中断逻辑或
6 赋值运算符
7 运算符优先级
六、JavaScript流程控制-分支结构导读
1 if分支语句
1.1 if语法结构:
1.2 if else语句(双分支语句)
1.3 if else if (多分支语句)
2 switch分支语句
3 三元表达式
七、JavaScript流程控制-循环结构导读
1 for循环
1.1 for循环执行过程
2 while循环
3 do while循环
4 continue break 关键字
5 JavaScript命名规范
八、JavaScript数组导读
1 创建数组
2 数组的索引
3 遍历数组
4 求数组中的最大值
5 数组转换为字符串
6 数组中新增元素
7 筛选数组
7.1 方法一
7.2 方法二
8 数组案例
8.1 删除指定数组元素
8.2 翻转数组
8.3 交换两个变量
8.4 数组排序 (冒泡排序)
九、函数导读
1 函数概念
2 函数使用
3 函数的封装
4 函数的参数
4.1 函数形参和实参匹配问题
4.2 参数小结
5 函数的返回值
5.1 return 终止函数
5.2 break continue return区别
6 arguments的使用
7 利用函数翻转数组
8 利用函数冒泡排序
9 利用函数判断闰年
10 函数相互调用
11 函数的两种声明方式
十、JavaScript作用域
1 作用域
1.1 全局作用域
1.2 局部作用域(函数作用域)
2 变量的作用域
3 作用域链
十一、JavaScript预解析
1 四个案例 作用域链
十二、JavaScript对象
1 对象
2 创建对象的三种方式
2.1 利用字面量
2.2 new Object
2.3 构造函数
3 new关键字
4 遍历对象属性
十三、JavaScript内置对象
1 什么是内置对象
2 根据文档查询制定API的使用方法
3 Math对象的常用方法
3.1 Math绝对值方法和三个取整方法
3.2 随机数方法random()
4 Date对象
4.1 日期格式化
4.2 获取日期的总的毫秒形式(时间戳)
4.3 倒计时案例 重点案例 以后经常用
5 Array对象
5.1 检测是否为数组两种方法
5.2 添加删除数组元素的方法
5.3 筛选数组 案例
5.4 数组排序
5.5 数组索引方法
5.6 数组去重(重点案例)
5.7 数组转换为字符串
6 String对象
6.1 基本包装类型
6.2 字符串的不可变
6.3 根据字符串返回位置
6.4 案例:查找字母出现的位置和次数
6.5 根据位置返回字符
6.6 案例:返回字符位置
7 字符串的操作方法(重点)
8 替换字符串以及转换为数组
9 数据类型内存分配
9.1 基本概念
9.2 简单类型传参
9.3 复杂类型传参
编程:就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。
计算机程序:就是计算机所执行的一系列的指令集合,而程序全部都是用我们所掌握的语言来编写的,所以人们要控制计算机一定要通过计算机语言向计算机发出指令。
计算机语言:是指用于人与计算机之间通讯的语言,它是人与计算机之间传递信息的媒介。计算机语言的种类非常的多,总的来说可以分成机器语言,汇编语言和高级语言三大类。实际上计算机最终所执行的都是机器语言,它是由“0”和“1”组成的二进制数,二进制是计算机语言的基础。
编程语言,可以通过类似于人类语言的“语言”来控制计算机,让计算机为我们做事情,这样的语言就叫做编程语言。
编程语言是用来控制计算机的一系列指令,它有固定的格式和词汇,不同编程语言的格式和词汇不一样,必须遵守。
如今通用的编程语言有两种形式:汇编语言和高级语言。
汇编语言和机器语言实质是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆。
高级语言主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,常用的有C语言、C++、Java、C#、Python、PHP、JavaScript、Go语言、Objective-C、Swift等。
C语言:puts("你好");
PHP:echo"你好";
Java:System.out.println("你好");
JavaScript:alert("你好");
编程语言与标记语言的区别
编程语言有很强的逻辑和行为能力。在编程语言里,你会看到很多if else、for、while等很多具有逻辑性和行为能力的指令,这是主动的。
标记语言(HTML)不用向计算机发出指令。常用于格式化和链接。标记语言的存在是用来被读取的,是被动的
计算机组成:硬件、软件
硬件组成:输入设备、输出设备、CPU、硬盘、内存
软件组成:系统软件、应用软件
布兰登·艾奇
1995年 10天完成JavaScript设计
网景公司最初命名为LiveScript,后来与Sun合作之后将其改名为JavaScript
JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(script是脚本的意思)
脚本语言:不需要编译,在运行过程中由js解释器(js引擎)逐行来进行解释并执行
现在也可以由基于Node.js技术进行服务器端编程
表单动态校验(密码强度检测)
网页特效
服务端开发(Node.js)
桌面程序(Electron)
App(Cordova)
控制硬件-物联网(Ruff)
游戏开发(cocos2d-js)
浏览器分为两部分 渲染引擎和JS引擎
渲染引擎:用来解析HTML和CSS,俗称内核,比如chrome浏览器的blink,老版本的webkit。
JS引擎:也称为JS解释器,用来读取网页中的JavaScript代码,对其处理后运行,比如chrome浏览的v8。
浏览器本身并不会执行JS代码,而是通过内置JavaScript引擎(解释器)来执行JS代码。JS引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以JavaScript语言归为脚本语言,会逐行解释执行。
ECMAScript JavaScript语法(规定了JS的编程语法和基础核心知识)
DOM 页面文档对象模型(标准编程接口,对页面上各种元素操作,大小、位置、颜色等)
BOM 浏览器对象模型(可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等)
第一类:行内式的js 直接写到元素内部
写在body内,例如:
第二类:内嵌式的js
写在head内,例如:
第三类:外部引入js文件
//标签中间不可以写代码
单行 // 快捷键ctrl+/
多行 /* 注释 */ vscode默认是shift+alt+a 可以修改 控制->键盘快捷方式
alert(msg); 浏览器弹出警示框
console.log(msg); 浏览器控制台打印输出信息
prompt(info); 浏览器弹出输入框,用户可以输入
简单来说,就是一个存放数据的容器,通过变量名获取数据,数据可以修改。
本质是 变量是程序在内存中申请的一块用来存储数据的空间。
两步 先声明变量 然后赋值
var age; //声明一个名称为age的变量
age=10; //把值10存到age中 赋值
console.log(age); //在控制台输出结果 18 (F12键调出控制台)
变量的初始化 声明一个变量并赋值
var myname = 'wyijie';
console.log(myname);
一个变量被重新赋值后,原有的值就会被覆盖,变量值将以最后一次赋的值为准。
var age = 19;
age = 81; //最后的结果是81 19被覆盖掉了
同时声明多个变量时,只用一个var就可以 多个变量名之间使用英文逗号隔开。
var age = 10, name = 'as', sex = 2;
var age;console.log(age); //undefined 只声明 不赋值
console.log(age); //报错 不声明 不赋值 直接使用
age = 10;console.log(age); //10 不声明 只赋值 虽然输出但不提倡
由字母、数字、下划线、美元符号组成
严格区分大小写
不以数字开头
不可以是关键字 (var for while)
变量名必须有意义
遵守驼峰命名法。首字母小写 后面单词首字母需要大写
推荐翻译网站:有道 爱词霸
在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。
变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的存储到计算机内存中。JavaScript是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行中,类型会被自动确定。
JS的变量数据类型是只有程序运行过程中,根据等号右边的值来确定的。
var str = 'red'; //str字符串型
JS是动态语言,变量的数据类型是可以变化的
var x = 10; //x是数字型
x = 'red'; //x是字符串型
Number 数字型,包含整型值和浮点型值,如21、0.21 默认0
infinity,代表无穷大,大于任何数值
-infinity,代表无穷小,小于任何数值
NaN,Not a number,代表一个非数值
alert(Number.MAX_VALUE);//1.7976931348623157e+308
alert(Number.MIN_VALUE);//5e-324
isNaN() 判断是否为数字 是返回ture 不是返回false
转义字符 \n换行符 \\斜杠\ \'单引号' \"双引号" \b空格 \t缩进tab
String 字符串类型,如"张三",在JS里字符串都带引号
length 检测字符串的长度
字符串拼接:字符串+任何类型=拼接之后新的字符串 数值相加,字符相连
字符串拼接加强:var age = 18;
console.log('我今年'+age+'岁了')
Boolean 布尔值类型,如true、false,等价于1和0 默认false
有两个值:true和false
Undefined var a;声明了变量a但是没有给值,此时默认a=undefined
undefined和数字相加,最后是NaN
Null var a = null;声明了变量a为空值 默认null
空值与数字相加,返回的是本来的数字
var num = 10;
console.log(typeof num);//number
var timer = null;
console.log(typeof timer);//object
把一种数据类型转换成另外一种数据类型。
toString() 案例:var num=1;alert(num.toString());
String() 强制转换 案例:var num=1;alert(String(num));
加号拼接字符串 和字符拼接的结果都是字符串
案例:var num=1;alert(num+"我是字符串");
parseInt(string)函数 将string类型转换为整数值型 parseInt('780')
parseFloat(string)函数 将string类型转换为浮点数值型 parseFloat('3.1')
Number() 强制转换函数 将string类型转换为数值型 Number('12')
js隐式转换(- * /) 利用算数运算隐式转换为数值型 '12'-0
//var age = prompt('请输入您的年龄');
//1. parseaInt(变量) 可以把字符型的转换为数字型 得到的是整数
//console.log(parseInt(age));
console.log(parseInt('3.14'));// 3 取整
console.log(parseInt('3.94'));// 3 取整
console.log(parseInt('120px'));// 120 会去掉这个px单位
console.log(parseInt('rem120px'));// NaN
//2.parseFloat(变量) 可以把字符型的转换为数字型 得到的是小数 浮点数
console.log(parseFloat('3.14'));// 3.14
console.log(parseFloat('120px'));// 120 会去掉px单位
console.log(parseFloat('rem120px'));//NaN
//3.利用Number(变量)
var str = '123';
console.log(Number(str));
console.log(Number('12'));
//4.(- * /) 利用算数运算隐式转换为数值型
console.log('12'-0);//12
console.log('123'-'120');//3
console.log('123'*1);//123
Boolean()函数
代表空、否定的值会被转换为false 如0、NaN、null、undefined
其余值都会被转换为true
console.log(Boolean(''));//false
console.log(Boolean(0));//false
console.log(Boolean(NaN));//false
console.log(Boolean(null));//false
console.log(Boolean(undefined));//false
console.log(Boolean('小白'));//true
console.log(Boolean(12));//true
标识符(zhi):就是指开发人员为变量、属性、函数、参数取得名字
标识符不能是关键字或保留字
关键字:是指JS本身已经使用了的字,不能再用它们充当变量名、方法名
包括:break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with等。
保留字;实际上就是预留的“关键字”,意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不能使用它们当变量名或方法名。
包括:boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、inplements、import、int、interface、long、mative、package、private、protected、public、short、atatic、super、aynchronized、throws、transident、volatile等。
运算符(operator)也被称为操作符,是用于实现赋值、比较和执行算数运算功能的符号。
常用的运算符有:算数运算符、递增递减运算符、比较运算符、逻辑运算符、赋值运算符
console.log(1 + 1); //2 符号左右加个空格 比较优雅
console.log(1 - 1); //0
console.log(1 * 1); //1
console.log(1 / 1); //1
console.log(5 % 2); //1 取余或取模 5除以2余1
表达式:是由数字、运算符、变量等组成的式子 1 + 1
表达式最终都会有一个结果返回,console.log(1 + 1);//2就是返回值
在我们程序里面 2 = 1 + 1 例:var num = 1 + 1;//右边计算完毕给左边num
递增(++)和递减(--)既可以放在变量前面,也可以放在变量后面,放在变量前面时,可以称为前置递增运算符,放在变量后面时,可以称为后置递增运算符。
注意:递增和递减运算符必须和变量配合使用。
var age=10;
++age; //类似于 age=age+1
console.log(age);//11
先自加1 后返回值
var num=10;
num++; //类似于 num=num+1
console.log(age);//11
先返回原值,后自加1
前置自增和后置自增如果单独使用 效果是一样的
var age=10;
console.log(age++ +10);//20 先返回原值10然后加10 就是20
console.log(age);//11 返回原值之后自加1 age此时就是11了
返回值ture 或 false
< 小于
> 大于
>= 大于等于
<= 小于等于
== 等于(会转型)
!= 不等于
=== !== 全等 要求值和数据类型都相同
逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。经常用于多个条件的判断。
//1. && 逻辑与 and 两侧都为true 结果才是true 只要有一侧为false 结果false
console.log(3 > 5 && 3 > 2);//false
console.log(3 < 5 && 3 > 2);//true
//2. || 逻辑或 or 两侧都为false 结果才为false 只要有一侧为true 结果就为true
console.log(3 > 5 || 3 > 2);//true
console.log(3 > 5 || 3 < 2);//false
//3. ! 逻辑非 not
console.log(!true);//false
短路运算(逻辑中断)运算原理:当有多个表达式时,左边的表达式值可以确定结果时,就不再继续右边的表达式的值。
逻辑与
语法:表达式1 && 表达式2
如果第一个表达式的值为真,则返回表达式2
如果第一个表达式的值为假,则返回表达式1
console.log(123 && 456);//456 除了0之外其他都是true
console.log(0 && 456);//0
console.log(0 && 1 + 2 && 456 * 56789);//0
console.log(0 && 1 + 2 && 456 * 56789);//0
console.log('' && 1 + 2 && 456 * 56789);//'' 返回空
逻辑或
语法:表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式的值为假,则返回表达式2
console.log(123 || 456);//123
console.log(0 || 456);//456
console.log(0 || 456 || 456 + 123);//456
= 直接赋值
+=、-= 加、减一个数 后赋值
*=、/=、%= 乘、除、取模 后赋值
1 小括号 ()
2 一元运算符 ++ -- !
3 算数运算符 先 * / % 后 + -
4 关系运算符 > >= > <=
5 相等运算符 == != === !==
6 逻辑运算符 先&& 后||
7 赋值运算符 =
8 逗号运算符 ,
流程控制:控制代码的执行顺序来实现要完成的功能。
有顺序结构(顺序执行)、分支结构(条件执行)、循环结构(循环执行)
根据不同条件 执行不同代码 得到不同结果(执行多选一的过程)
if(条件表达式){
//执行语句
}
//执行思路:如果if里的表达式结果为真true 则执行大括号里的语句 如果为假 则执行if语句后的代码。
if(3 > 5){
alert('真爱至上');
}
if(条件表达式){
//执行语句1
}else{
//执行语句2
}
//执行思路:如果表达式结果为真 那么执行语句1 否则 执行语句2
if(条件表达式1){
//执行语句1
}else if(条件表达式2){
//执行语句2
}else if(条件表达式3){
//执行语句3
}else if(条件表达式4){
//执行语句4
}else{
//执行最后的语句
}...
//执行思路:从上往下 如果表达式1结果为真 那么执行语句1 否则 判断条件表达式2 满足执行语句2 不满足继续往下执行条件表达式3 如果都不满足 执行最后的语句
也是多分支语句,主要是针对变量设置一系列的特定值的选项时,就可以使用switch。
switch(表达式){
case value1:
执行语句1;
break;
case value2:
执行语句2;
break;
...
default:
执行最后的语句;
}
//执行思路:匹配 表达式的值与case后的value值匹配 匹配成功执行语句 执行不满足条件 执行default最后的语句
条件表达式 ? 表达式1 : 表达式2
如果条件表达式结果为真 则 返回表达式1的值
如果条件表达式结果为假 则 返回表达式2的值
在程序中,一组被重复执行的语句称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句。
结构:
for(初始化变量;条件表达式;操作表达式){
//循环体
}
初始化变量 就是用var 声明一个普通变量 通常用于作为计数器使用
条件表达式 就是用来决定每一次循环是否继续执行 就是终止的条件
操作表达式 是每次循环最后执行的代码 经常用于我们计数器变量
for(var i = 1; i <= 100; i++){
console.log('hello');
}
1.首先执行里面的计数器变量var i = 1; 这句话在for循环中只执行一次 i是index
2.然后去 i <= 100来判断是否满足条件,如果满足条件 就去执行循环体 不满足退出循环
3.最后去执行 i++ i++是单独写的代码 递增 第一轮结束
4.接着去执行 i <= 100 如果满足条件 就去执行循环体 不满足退出循环 第二轮
案例:打印九九乘法表 双重for循环
案例分析:一共有9行,但是每行的个数不一样,因此需要用到双重for循环
外层的for循环控制行数i,循环9次,可以打印9行
内层的for循环控制每行公式j
核心算法:每一行公式的个数正好和行数一致,j<=i;
每行打印完毕,都需要重新换一行
代码:
var str = '';
for(var i = 1; i <= 9; i++){ //外层循环控制行数
for(var j = 1; j <= i; j++){ //内层循环控制每一行的个数
str += j + 'x' + i + '=' + i * j + '\t';
}
str += '\n';
}
console.log(str);
while(条件表达式){
//循环体
}
//执行思路 当表达式结果为true 则执行循环体 否则 退出循环体
do{
//循环体
}while(条件表达式)
//执行思路 跟while循环不同的是,do while 先执行一次循环体 再判断条件 如果条件表达式结果为true 则继续执行循环体 否则退出循环
continue; 关键字用于立即跳出本次循环,继续下一次循环
break; 关键字用于立即跳出整个循环,循环结束
标识符:
变量、函数的命名必须要有意义
变量的名称一般用名词
函数的名称一般用动词
操作符:
左右两侧要有空格 j <= 12;
单行注释:
// 后要有一个空格
数组是指一组数据的集合,其中的每个数据被称为元素,在数组中可以存放任意类型的元素。数据是一种将一组数据存储在单个变量名下的优雅方式。
普通变量只能存储一个值,数组一次可以存储多个值
var arr = [1,2,3,4,5];
1.利用new创建数组 var arr = new Array(); // 创建了一个空的数组
2.利用数组字面量创建数组(常见)var 数组名 = []; // 方括号 数组
var arr1 = [1,2,'再见爱人',true]; // 要用逗号分隔 方括号里的称为数组元素 数组元素类型-任意类型 布尔、字符串、数字...
索引(下标):用来访问数组元素的序号(数组下标从0开始)。
获取数组元素 格式 数组名[索引号]
console.log(arr1[2]); // 再见爱人
遍历:就是把数组中的每个元素从头到尾访问一次。
var arr1 = [1,2,'再见爱人',true];
for (var i = 0; i < 4; i++){
console.log(arr1[i]);
}
// 求数组[2,6,1,77,52,25,7]中的最大值
// 声明一个保存最大元素的变量max
// 默认最大值可以取数组中的第一个元素
// 遍历这个数组,把里面的每个数组元素和max比较
// 如果这个数组元素大于max 就把这个数组元素存到max里面,否则继续下一轮比较
// 最后输出这个max
var arr = [2,6,1,77,52,25,7,99];
var max = arr[0];
for(var i = 1; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
console.log('该数组里面最大的值是:' + max);
// 将数组['red','green','blue','pink']转换为字符串,并且用 | 或其它符号分割
// 1.需要遍历一个新变量用于存放转换完的字符串 str
// 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面
// 3.同时在后面多加一个分隔符
var arr = ['red','green','blue','pink'];
var str = '';
var sep = '*';
for(var i = 0; i < arr.length; i++){
str += arr[i] + sep;
}
console.log(str);
// 1.新增数组元素 修改length长度
var arr = ['red','green','blue'];
console.log(arr.length);
arr.length = 5; // 把我们的数组的长度修改为了 5 里面应该有5个元素
console.log(arr);
console.log(arr[3]); // undefined
console.log(arr[4]); // undefined
// 2.新增数组元素 修改索引号 追加数组元素
var arr1 = ['red','green','blue'];
arr1[3] = 'pink';
console.log(arr1); // ["red","green","blue","pink"]
arr1[4] = 'hotpink';
console.log(arr1); // ["red","green","blue","pink","hotpink"]
arr1[0] = 'yellow'; // 这里是替换原来的数组元素
console.log(arr1); //["yellow","red","green","blue","pink","hotpink"]
arr1 = '再见爱人';
console.log(arr1); // 不要直接给数组名赋值 否则里面的数组元素都没有了
将数组 [2,0,6,1,77,0,52,0,25,7]中大于等于 10 的元素选出来 放入新数组
// 1.声明一个新的数组用于存放新数据newArr
// 2.遍历原来的旧数组,找出大于等于10的元素
// 3.依次追加给新数组 newArr
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
var j = 0;
for(var i = 0; i < arr.length; i++){
if(arr[i] > 10){
// 新数组索引号应该从0开始 依次递增
newArr[j] = arr[i];
j++;
}
}
console.log(newArr); // (3) [77,52,25]
// 方法2
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
// 刚开始newArr.length 就是0
for(var i = 0; i < arr.length; i++){
if(arr[i] >= 10){
// 新数组索引号应该从0开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
// 要求:将数组[2,0,6,1,77,0,52,0,25,7]中的0去掉后,形成一个不包含0的新数组
// 1.需要一个新数组用于存放筛选之后的数据
// 2.遍历原来的数组 把不是0的数据添加到新数组里面(此时要注意采用数组名 + 索引的格式接收数据)
// 3.新数组里面的个数 用length不断累加
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
for(var i = 0; i < arr.length; i++){
if(arr[i] != 0){
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
// 要求:将数组['red','green','blue','pink','purple']的内容反过来存放
// 输出:['purple','pink','blue','green','red']
// 核心:把arr 的最后一个元素 取出来 给 新数组 作为第一个
// 1.声明一个新数组 newArr
// 2.把旧数组索引号第四个取过来(arr.length-1)给新数组索引号第0个元素(newArr.length)
// 3.我们采取 递减的方式 i--
var arr = ['red','green','blue','pink','purple'];
var newArr = [];
for(var i = arr.length - 1; i >= 0; i--){
newArr[newArr.length] = arr[i];
}
console.log(newArr);
var num1 = 10;
var num2 = 20;
var temp;
temp = num1;
num1 = num2;
num2 = temp;
console.log(num1,num2); // 20 10
冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)
冒泡排序是一种简单的排序算法。它重复的走访过要排列的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
var arr [5,4,3,2,1];
for(var i = 0; i <= arr.length - 1; i >= 0; i++){ // 外层循环
for(var j = 0; j <= arr.length - i - 1; j++){ // 里层循环
//内部交换2个变量的值 前一个和后面一个数组元素相比较
if(arr[i] > arr[j + 1]){
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
// 1.求1~100的累加和
var sum = 0;
for(var i = 1; i <= 100; i++){
sum += i;
}
console.log(sum);
// 2.求1~100的累加和
var sum = 0;
for(var i = 10; i <= 50; i++){
sum += i;
}
console.log(sum);
// 在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量的重复使用。
// 虽然for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS中的函数。
// 函数:就是封装了一段可被重复调用执行的代码块。通过代码块可以实现大量代码的重复使用。
// 3.函数
function getSum(num1,num2){
var sum = 0;
for(var i = num1; i <= num2; i++){
sum += i;
}
console.log(sum);
}
getSum(1,100);
getSum(10,50);
getSum(1,1000);
// 函数使用分为两步:声明函数 和 调用函数
// 1.声明函数:
// function 函数名(){
//函数体
// }
function sayHi() {
console.log('hi~~');
}
// function声明函数的关键字 全部小写
// 函数是做某种事情,函数名一般是动词 sayHi
// 函数不调用自己不执行
// 2.调用函数
sayHi();
// 调用函数的时候千万不要忘记加小括号
函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
简单理解:封装类似于将电脑配件整合组装到机箱中(类似于快递打包)
function getSum(){
var sum = 0;
for(var i = 1; i <= 100; i++){
sum += i;
}
console.log(sum);
}
getSum();
形参和实参
函数的参数可以有 也可以没有 个数不限
function 函数名(形参1,形参2...){ // 形式上的参数
}
函数名(实参1,实参2...); // 实际的参数
function cook(aru){ // 形参是接收实参的 aru = '酸辣土豆丝'
console.log(aru);
}
cook('酸辣土豆丝');
cook('大肘子'); // 大肘子
// 函数形参实参个数匹配
function getSum(num1,num2){
console.log(num1 + num2);
}
// 1.如果实参的个数和形参的个数一样 则正常输出结果
getSum(1, 2);
// 2.如果实参的个数多于形参的个数 会取到形参的个数
getSum(1, 2, 3);
// 3.如果实参的个数小于形参的个数
// 形参可以看作是不用声明的变量 num2 是一个变量但是没有接收值 结果就是undefined
getSum(1); // NaN
// 建议 我们尽量让实参的个数和形参相匹配
函数可以带参数也可以不带参数
声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
调用函数的时候,函数名括号里面的是实参
多个参数中间用逗号分隔
形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
格式:
function 函数名(){
return 需要返回的结果;
}
函数名();
// 1.我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名() 通过return实现的
// 2.只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
// 3.代码验证
function getResult(){
return 666;
}
getResult(); // getResult() = 666
console.log(getResult());
// 4.求任意两个数的和
function getSum(num1,num2){
return num1 + num2;
}
console.log(getSum(1,2));
// 1. return后的代码是不会执行的
function getSum(num1,num2){
return num1 + num2; // return后的代码是不会执行的
alert('我是并不会被执行的哦!')
}
console.log(getSum(1,2)); // 3
// 2. return只能返回一个值
function fn(num1,num2){
return num1, num2; // 返回的结果是最后一个值
}
console.log(fn(1,2)); // 2
break 结束当前的循环体,如for、while
continue 跳出本次循环,继续执行下次循环,如for、while
return 不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码
当我们不确定有多少个参数传递的时候,可以用arguments来获取。
在JavaScript中,arguments实际上的它是当前函数的一个内置对象。
所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
具有length属性
按索引方式储存数据
不具有数组的push,pop等方法
// arguments 使用
// 只有函数有arguments 而且是每个函数都内置好了这个arguments
function fn(){
console.log(arguments); // 里面存储了所有传递过来的实参
console.log(arguments.length);
console.log(arguments[2]);
// 我们可以按照数组的方式遍历arguments
for (var i = 0; i < arguments.length; i++){
console.log(arguments[i]);
}
}
fn(1,2,3);
fn(1,2,3,4,5);
// reverse 翻转
function reverse(arr){
var newArr = [];
for(var i = arr.length - 1; i >= 0; i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1,3,4,6,9]);
console.log(arr1);
var arr2 = reverse(['pink','red','blue']);
console.log(arr2);
// sort 排序
function sort(arr){
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 temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1,4,2,9]);
console.log(arr1);
var arr2 = sort([11,7,22,999]);
console.log(arr2);
function isRunYear(year){
// 如果是闰年我们返回 true 否则 返回false
var flag = false;
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
console.log(isRunYear(1999));
function fn1(){
console.log(11);
fn2(); // 在fn1 函数里面调用了 fn2函数
}
fn1();
function fn2(){
console.log(22);
}
第一种 利用函数关键字自定义函数
function fn(){
}
fn();
第二种 函数表达式
var 变量名 = function(){};
var fun = function(aru){
console.log('我是函数表达式');
console.log(aru);
}
fun('pink');
// (1) fun 是变量名 不是函数名
// (2) 函数表达式声明方式跟声明变量差不多 只不过变量里存的是值 而函数表达式里存的是函数
// (3) 函数表达式也可以进行传递参数
就是代码名字(变量)在某个范围内起作用和效果。
目的是为了提供程序的可靠性 更重要的是减少命名冲突。
JavaScript作用域(es6)之前:全局作用域 局部作用域
es6有块级作用域
块级作用域:在花括号里面声明 {} if{} for{}
整个script标签 或者是一个单独的js文件 起作用
在函数内部就是局部作用域 这个代码只在函数内部起效果和作用
// 变量的作用域:根据作用域的不同我们变量分为全局变量和局部变量
// 1.全局变量:在全局作用域下的变量 在全局下都可以使用
// 如果在函数内部 没有声明 直接赋值的变量也是全局变量
var num = 10; // num就是一个全局变量
console.log(num);
function fn(){
console.log(num);
}
fn();
// 2.局部变量 在局部作用域下变量 后者在函数内部的变量就是 局部变量
function fun(){
var num1 = 10; // num1就是局部变量 只能在函数内部使用
num2 = 20;
}
fun();
console.log(num1); // 会报错
console.log(num2); // 20 num2是全局变量
// 3.从执行效率来看全局变量和局部变量
// 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
// 局部变量 当我们程序执行完毕时就会销毁,比较节约内存资源
// 只要是代码 就至少有一个作用域
// 写在函数内部的局部作用域
// 如果函数中还有函数 那么在这个作用域中就又可以诞生一个作用域
// 根据在内部函数可以访问外部函数变量的这种机制 用链式查找决定哪些数据能被内部函数访问 就称作作用域链
// 作用域链:内部函数访问外部函数的变量采取的链式查找的方式来决定取哪个值 这种结构称为作用域链
var num = 10;
function fn(){ // 外部函数
var num = 20;
function fun(){ // 内部函数
console.log(num);
}
}
1.js引擎运行js 分为两步 : 预解析 代码执行
预解析:js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
代码执行:按照代码书写的顺序从上往下执行
2.预解析分为变量预解析(变量提升)和函数预解析(函数提升)
变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
函数提升 就是把所有的函数声明提升到当前的作用域最前面 不调用函数
// 先提变量var 再提函数
// 案例1
var num = 10;
fun();
function fun(){
console.log(num);
var num = 20;
}
// 相当于执行了以下操作
var num;
function fun(){
var num;
console.log(num); // undefined
num = 20;
}
num = 10;
fun();
// 案例2
var num = 10;
function fn(){
console.log(num);
var num = 20;
console.log(num);
}
fn();
// 相当于执行了以下操作
var num;
function fn(){
var num;
console.log(num); // undefined
num = 20;
console.log(num); // 20
}
num = 10;
fn();
// 案例3
var a = 18;
f1();
function f1(){
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
// 相当于执行了以下操作
var a;
function f1(){
var b;
var a;
b = 9;
console.log(a); // undefined
console.log(b); // 9
a = '123';
}
a = 18;
f1();
// 案例4
f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){
var a = b = c = 9;
// 相当于 var a = 9; b = 9; c = 9; b和c直接赋值 没有var声明 相当于全局变量
// 而集体声明 var a = 9, b = 9, c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 相当于执行了以下操作
function f1(){
var a;
a = 9;
b = 9;
c = 9;
console.log(a); // 9
console.log(b); // 9
console.log(c); // 9
}
f1();
console.log(c); // 9
console.log(b); // 9
console.log(a); // 报错
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的。
属性:事物的特征,在对象中用属性来表示(常用名词)
方法:事物的行为,在对象中用方法来表示(常用动词)
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果要保存一个人的完整信息呢?
对象字面量:就是花括号{}里面包含了表达这个具体事物(对象)的属性和方法。
// var obj = {}; // 创建了一个空的对象
// 1.创建对象
var obj = {
uname: '张三丰',
age: 18,
sex: '男',
sayHi: function(){
console.log('hi~');
}
}
// (1) 里面的属性或者方法采用键值对的形式 键 属性名:值 属性值
// (2) 多个属性或者方法中间用逗号隔开
// (3) 方法冒号后面跟的是一个匿名函数
// 2.使用对象
// (1)调用对象的属性 我们采取 对象名.属性名
console.log(obj.uname); // 张三丰
// (2)调用属性还有一种方法,对象名['属性名']
console.log(obj['age']); // 18
// (3) 调用对象的方法 sayHi 对象名.方法名() 千万别忘记添加小括号
obj.sayHi(); // hi~
var obj = new Object(); // 创建了一个空对象
obj.uname = '张三丰';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function(){
console.log('hi~');
}
// 利用等号 = 赋值的方法 添加对象的属性和方法
// 每个属性和方法之间用 ; 分号结束
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
我们为什么需要构造函数?
就是因为前面两种创建函数对象的方式一次只能创建一个对象。
因为我们一次创建一个对象,里面很多的属性和方法是大量相同的 我们只能复制。
因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为 构造函数。
又因为这个函数不一样 里面封装的不是普通代码 而是对象。
构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面。
我们利用构造函数创建对象的过程也称为对象的实例化
语法格式:
function 构造函数名(){
this.属性 = 值;
this.方法 = function(){
}
}
new 构造函数名();
统一规范 :
1.构造函数名首字母大写 就是要不一样
2.我们构造函数不需要return 就可以返回结果
3.我们调用构造函数 必须使用new
4.我们只需要new Star () 调用函数就创建一个对象 ldh {}
5.我们的属性和方法 前面必须加 this
例子:
我们需要创建四大天王的对象
把公共的抽取出来 相同属性:名字、年龄、性别、相同的方法:唱歌 等
把相同的封装到一起
// 1.构造函数 叫Star 明星 泛指的某一大类
function Star(uname,age,sex){
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang){
console.log(sang);
}
}
// 2.对象 是一个具体的事物 刘德华
var ldh = new Star('刘德华', 18, '男');
console.log(ldh.name);
console.log(ldh['sex']);
ldh.sing('凉凉');
// 你也没有对象吗? new一个不就好了 哈哈哈
var zxy = new Star('张学友', 19, '男');
console.log(zxy.name);
console.log(zxy.age);
zxy.sing('上山');
function Star(uname,age,sex){
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang){
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男');
new关键字执行过程:
1.new构造函数可以在内存中创建了一个空的对象
2.this 就会指向刚才创建的空对象
3.执行构造函数里面的代码 给这个空对象添加属性和方法
4.返回这个对象 (所以构造函数里不需要return)
var obj = {
name:'吴';
age:18;
sex:'女';
fn:function(){}
}
//console.log(obj.name);
//console.log(obj.age);
//console.log(obj.sex);
//for in 遍历对象
//语法格式:
//for (变量 in 对象){
//
//}
for (var k in obj){
console.log(k); // k 变量 输出 得到的是属性名
console.log(obj[k]); // obj[k] 得到的是 属性值
}
// 我们使用 for in 里面的变量 我们喜欢写 k 或者 key
JavaScript中的对象分为三种:自定义对象、内置对象、浏览器对象。
前面两种是JS基础内容,属于ECMAScript。
第三个浏览器对象属于我们JS独有的 我们JS API讲解。
内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。。
内置对象最大的优点就是帮助我们快速开发。
JavaScript提供了多个内置对象:Math、Date、Array、String等。
内置对象有很多,方法也有很多,忘了查一下哈
两种 MDN 和 W3C
MDN更普遍更常用
MDN网址:https://developer.mozilla.org/zh-CN/
在搜索框输入 回车搜索
右上角 language 选择中文简体 看中文
如何学习对象中的方法呢
1.查阅该方法的功能
2.查看里面的参数的意义和类型
3.查看返回值的定义和类型
4.通过demo进行测试 有示例
Math数学对象 可以直接输入Math 搜索一下 按照步骤
Math数学对象 不是一个构造函数 所以我们不需要new 来调用 而是直接使用里面的属性和方法即可
console.log(Math.PI); // 一个属性 圆周率
console.log(Math.max(1,99,3)); //99
console.log(Math.max(-1,10)); // -1
console.log(Math.max(1,99,'pink')); // NaN
console.log(Math.max()); // -Infinity
// 1.绝对值方法
console.log(Math.abs(1)); // 1
console.log(Math.abs(-1)); // 1
console.log(Math.abs('-1')); // 隐式转换 会把字符串型-1 转换为数字型
console.log(Math.abs('pink')); // NaN
// 2.三个取整方法
// (1) Math.floor() 地板 向下取整 往最小了取
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
// (2) Math.ceil() 天花板 向上取整 往最大了取
console.log(Math.ceil(1.1)); // 1
console.log(Math.ceil(1.9)); // 1
// (3) Math.round() 四舍五入 0.5特殊 往大了取
console.log(Math.round(1.1)); // 1
console.log(Math.round(1.5)); // 2
console.log(Math.round(1.9)); // 2
console.log(Math.round(-1.1)); // -1
console.log(Math.round(-1.5)); // -1 往大了取
// 1.random() 返回一个随机的小数 0 =< x < 1
// 2.这个方法里面不跟参数
// 3.代码验证
console.log(Math.random);
// 4.我们想要得到两个数之间的随机整数 并且 包含这2个整数
//Math.floor(Math.random() * (max - min + 1)) + min;
function getRandom(min,max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(1,10));
// 5.随机点名
var arr = ['小张','小李','小田','小吴','小白'];
console.log(arr[getRandom(0,arr.length - 1)]);
Date日期对象
可以查阅文档MDN
Date日期对象 是一个构造函数 必须使用new 来调用创建我们的日期对象
var arr = new Array(); // 创建一个数组对象
var obj = new Object(); // 创建一个对象实例
// 1.使用Date 如果没有参数 返回当前系统的当前时间
var date = new Date();
console.log(date);
// 2.参数常用的写法 数字型 2020,10,01 或者是 字符串型 '2020-10-1 9:9:9'
var date1 = new Date(2020,10,1);
console.log(date1); // 返回的是11月 不是10月
var date2 = new Date('2020-10-1 9:9:9');
console.log(date2);
var date = new Date();
console.log(date.getFullYear()); // 返回当前日期的年
console.log(date.getMonth() + 1); // 返回的月份小一个月 记得+1 (0-11)
console.log(date.getDate()); // 返回的是几号
console.log(date.getDay()); // 周一返回的是1 周六返回的是6 周日是0
// 我们写一个 2019年 5月 1日 星期三
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date.getDay();
console.log('今天是:' + year + '年' + month + '月' + date + '日' + arr[day]);
// 格式化日期 时分秒
var date = new Date();
console.log(date.getHours()); // 时
console.log(date.getMinutes()); // 分
console.log(date.getSeconds()); // 秒
// 要求封装一个函数返回当前的时分秒 格式 08:08:08
function getTime(){
var time = new Date();
var h = time.getHours();
h = h < 10 ? '0' + h : h;
var m = time.getMinutes();
m = m < 10 ? '0' + m : m;
var s = time.getSeconds();
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
console.log(getTime());
毫秒数永远都不会重复 很有意义
Date对象是基于1970年1月1日(世界标准时间)起的毫秒数
// 1.通过 valueOf() getTime()
var date = new Date();
console.log(date.valueOf());
console.log(date.getTime());
// 2.简单的写法 是常用的写法
var date1 = +new Date(); // +new Date() 返回的就是总的毫秒数
console.log(date1);
// 3.更简单的 h5新增的获得总的毫秒数
console.log(Date.now()); // Date 的D 必须大写
核心算法:
1.输入的时间减去现在的时间就是剩余的时间,即倒计时,但是不能拿着时分秒相减,比如05分减去25分 结果会是负数的
2.所以可以用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
3.把剩余的时间的毫秒数转换为天、时、分、秒(时间戳转换为时分秒)
4.转换公式如下:
d = parseInt(总秒数/60/60/24); // 计算天数
h = parseInt(总秒数/60/60%24); // 计算小时
m = parseInt(总秒数/60%60); // 计算分数
s = parseInt(总秒数%60); // 计算当前秒数
5.倒计时例子
function countDown(time){
var newTime = +new Date(); // 返回的是当前时间总的毫秒数
var inputTime = +new Date(time); // 返回的是用户输入时间的总毫秒数
var times = (inputTime - nowTime) / 1000; // time是剩余时间总的毫秒数
var d = parseInt(times / 60 / 60 / 24); // 天
d = d < 10 ? '0' + d :d;
var h = parseInt(times /60 / 60 % 24); // 小时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); // 秒数
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2019-5-1 18:00:00'));
var date = new Date();
console.log(date);
数组对象
查阅文档
// 1.翻转数组
function reverse(arr){
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}
console.log(reverse([1,2,3]));
console.log(reverse(1,2,3)); // 不是数组 没法处理
// 2.检测是否为数组
// (1) instanceof 运算符 它可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(arr instanceof Aarry);
console.log(obj instanceof Aarry);
// 所以上面的1.翻转数组应该这么写 去检测是否为数组
function reverse(arr){
// if(Array.isArray(arr)){}
if (arr instanceof Array){
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}else{
return 'error 这个参数要求必须是数组格式[1,2,3]'
}
}
console.log(reverse([1,2,3]));
console.log(reverse(1,2,3)); // error 这个参数要求必须是数组格式[1,2,3]
// (2) Array.isArray(参数); h5新增方法 ie9以上版本支持
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); //false
// 1. push(参数1...) 末尾添加一个或多个元素,注意修改原数组 并返回新的长度
var arr = [1,2,3];
arr.push(4,'pink');
console.log(arr);
// (1) push是可以给数组追加新的元素
// (2) push() 参数直接写 数组元素 就行
// (3) push完毕之后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// 2. unshift 在我们数组的开头 添加一个或者多个数组元素
console.log(arr.unshift('red', 'yellow'));
console.log(arr);
// (1) unshift是可以给数组前面追加新的元素
// (2) unshift() 参数直接写 数组元素 就行
// (3) unshift完毕之后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// 3. pop() 可以删除数组的最后一个元素
console.log(arr.pop());
console.log(arr);
// (1) pop是可以删除数组最后一个的元素 记住一次只能删除一个元素
// (2) pop() 没有参数
// (3) pop完毕之后,返回的结果是 删除的那个元素
// (4) 原数组也会发生变化
// 4. shift() 可以删除数组的第一个一个元素
console.log(arr.shift());
console.log(arr);
// (1) shift是可以删除数组第一个的元素 记住一次只能删除一个元素
// (2) shift() 没有参数
// (3) shift完毕之后,返回的结果是 删除的那个元素
// (4) 原数组也会发生变化
// 要求 有一个包含工资的数组[1500,1200,2100,2000,1800]; 要求把数组中工资超过2000的删除,剩余的放到新数组里面
var arr = [1500,1200,2100,2000,1800];
var newArr = [];
for (var i = 0; i < arr.length; i++){
if(arr[i] < 2000){
// newArr[newArr.length] = arr[i];
new.push(arr[i]);
}
}
console.log(newArr);
// 1.翻转数组
var arr = ['pink','red','blue'];
arr.reverse();
console.log(arr);
// 2.数组排序(冒泡排序)
var arr1 = [3,4,7,1];
arr1.sort(); //sort也有弊端 只支持个位数
console.log(arr1);
// 新增一个函数 按照某种顺序去进行排列
var arr1 = [13,4,77,1,7];
arr1.sort(function(a,b){
// return a - b; //升序的顺序排列
return b - a; //降序的顺序排列
});
console.log(arr1);
// 返回数组元素索引号方法 indexOf(数组元素) 作用就是返回该数组元素的索引号
// 他只返回第一个满足条件的索引号
// 它如果在该数组内找不到元素,则返回的是 -1
var arr = ['red','green','blue','pink','blue'];
console.log(arr.indexOf('blue'));
// 返回数组元素索引号方法 lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从后面开始查找
console.log(arr.lastIndexOf('blue')); // 4
有一个数组['c','a','z','a','x','a','x','c','b']
把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重。
核心算法:
1.我遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,就添加,否则不添加。
2.我们怎么知道该元素没有存在?利用新数组.indexOf(数组元素) 如果返回是 -1 就说明新数组里面没有该元素
// 封装一个 去重的函数 unique 独一无二的
function unique(arr){
var newArr = [];
for (var i = 0; i < arr.length; i++){
if(newArr.indexOf(arr[i]) === -1){
newArr.push(arr[i]);
}
}
return newArr;
}
var demo = unique(['c','a','z','a','x','a','x','c','b'])
console.log(demo);
// 1. toString() 将我们的数组转换为字符串
var arr = [1,2,3];
console.log(arr.toString()); // 1,2,3
// 2. join(分隔符)
var arr1 = ['pink','blue';'green'];
console.log(arr1.join()); // pink,blue,green
console.log(arr1.join('-')); // pink-blue-green
console.log(arr1.join('&')); // pink&blue&green
// 基本包装类型
var str = 'andy';
console.log(str.length);
// 对象 才有 属性和方法 复杂数据类型才有 属性和方法
// 简单数据类型为什么会有length 属性呢?
// 基本包装类型: 就是把简单的数据类型 包装成了 复杂数据类型
// (1) 把简单类型包装为复杂数据类型
var temp = new String('andy');
// (2) 把临时变量的值 给 str
str = temp;
// (3) 销毁这个临时变量
temp = null;
var str = 'andy';
console.log(str);
str = 'red';
console.log(str); // red
// 字符串的不可变
// 指的是里面的值不可变 虽然看上去可以改变内容 但其实地址变了 内存中新开辟了一个内存空间
// 所以不要大量的拼接字符串
字符串所有的方法,都不会修改字符串本身(字符串本身是不可变的),操作完成会返回一个新的字符串。
// 字符串对象 根据字符返回位置 str. indexOf('要查找的字符',[起始的位置])
var str = '离离原上草';
console.log(str.indexOf('原'));
console.log(str.indexOf('原',3)); // 从索引号是 3的位置开始往后查找
// 查找字符串 "abcoefoxyozzopp" 出现的位置和次数
// 核心算法:先查找第一个o出现的位置
// 然后 只要indexOf 返回的结果不是-1 就继续往后查找
// 因为indexOf 只能查找到第一个 所以后面的查找 一定是当前索引+1 从而继续查找
var str = "abcoefoxyozzopp";
var index = str.indexOf('o');
var num = 0;
while(index !== -1){
console.log(index);
num++;
index = str.indexOf('o',index + 1);
}
console.log('o出现的次数是:' + num);
// 1.charAt(index) 根据位置返回字符
var str = 'andy';
console.log(str.charAt(3));
// 遍历所有的字符
for (var i = 0; i < str.length; i++){
console.log(str.charAt(i));
}
// 2. charCodeAt(index) 返回相应索引号的字符ASCII的值 目的: 判断用户按下了哪个键
console.log(str.charCodeAt(0)); // 97
// 3. str[index] H5新增的
console.log(str[0]);
// 判断一个字符串 "abcoefoxyozzopp" 出现次数最多的字符,并统计其次数
// 核心算法:利用charAt() 遍历这个字符串
// 把每个字符都存储给对象 如果对象没有该属性,就为1 如果存在了就 +1
// 遍历对象 得到最大值和该字符
var str = "abcoefoxyozzopp";
var o = {};
for(var i = 0; i < str.length; i++){
var shars = str.charAt(i); // chars是字符串的每一个字符
if(o[chars]){ // o[chars]得到的是属性值
}else{
o[chars] = 1;
}
}
console.log(o);
// 2.遍历对象
var max = 0;
var ch = '';
for(var k in o){
// k 得到的是属性名
// o[k] 得到的是属性值
if(o[k] > max){
max = o[k];
ch = k;
}
}
console.log(max);
console.log('最多的字符是:' + ch);
// 字符串的操作方法
// 1. concat('字符串1','字符串2',...)
var str = 'andy';
console.log(str.concat('red'));
// 2. substr('截取的起始位置','截取几个字符');
var str1 = '吹吹';
console.log(str1.substr(2,2)); // 第一个2 是索引号的2 从第几个开始 第二个是2 是取几个字符
// 1.替换字符replace('被替换的字符','替换为的字符') 它只会替换第一个字符
var str = 'andyandy';
console.log(str.replace('a','b'));
// 有一个字符串 "abcoefoxyozzopp" 要求把里面所有的 o 替换为 *
var str1 = "abcoefoxyozzopp";
while(str1.indexOf('o') !== -1){
str1 = str1.replace('o','*');
}
console.log(str1);
// 2. 字符转换为数组 splif('分隔符') 前面我们学过join 把数组转换为字符串
var str2 = 'red,pink,blue';
console.log(str2.split(','));
var str3 = 'red&pink&blue';
console.log(str3.split('&'));
简单数据类型又叫做基本数据类型,复杂数据类型又叫做引用类型。
值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。
string,number,boolean。undefined,null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。
通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
堆和栈
堆栈空间分配区别:
栈(操作系统): 由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。
简单数据类型存放到栈里面。
堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
复杂数据类型存放到堆里面。
// 简单数据类型 null 返回的是一个空的对象 object
var timer = null;
console.log(typeof timer);
// 如果有个变量我们以后打算存储为对象 暂时没想好放啥