1.数组
1.1 数组的概念
数组的作用:数组(Array)可以把一组相关的数据一起存放在单个变量下,并提供方便的访问(获取)方式。
数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素****。数组是一种将一组数据存储在单个变量名下的优雅方式。
//普通变量一次只能存储一个值
var num = 10;
//数组一次可以存储多个值
var arr = [1,2,3,4,5];
1.2 数组的创建方式
JS中创建数组有两种方式:
- 利用new创建数组
- 利用数组字面量创建数组
1.2.1 利用new创建数组
var 数组名 = new Array() ;
var arr = new Array () ;//创建一个新的空数组
- 这种方式暂且了解,等学完对象再看
- 注意Array(),A要大写
1.2.2 利用数组字面量创建数组
字面量:看到这个字符,就知道是什么数据类型的。
// 1.使用数组字面量方式创建空的数组
var 数组名 = [ ];
// 2.使用数组字面量方式创建带初始值的数组
var 数组名 = ['小白','小黑', '大黄','瑞奇'];
- 数组的字面量是方括号[]
- 声明数组并赋值称为数组的初始化
- 这种字面量方式也是我们以后最多使用的方式
1.2.3 数组元素的类型
数组中可以存放任意类型的数据,例字符串,数字,布尔值等。
var arrstus =[ '小白',12,true,28.9];
1.3 获取数组中的元素
1.3.1 数组的索引
索引(下标)∶用来访问数组元素的序号(数组下标从0开始)。
数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过“数组名[索引]”的形式来获取数组中的元素。
这里的访问就是获取得到的意思
//定义数组
var arrStus =[1,2,3];
//获取数组中的第2个元素
alert (arrStus[1]);
1.3.2 遍历数组
使用“数组名.length”可以访问数组元素的数量(数组长度)。
var arrStus =[1,2,3];
for (var i = 0; i < arrStus.length; i++) {
console.log(arrStus[i]);
}
1.4 数组中新增元素
可以通过修改length长度以及索引号增加数组元素
1.4.1 通过修改length长度新增数组元素
- 可以通过修改length长度来实现数组扩容的目的
- length属性是可读写的
var arr =[ " red' , "green ' , "blue" , "pink " ];
arr.length = 7;
console.log(arr) ;
console.log(arr[4] );
console.log(arr[5]) ;
console. log(arr[6]) ;
其中索引号是4,5,6的空间没有给值,就是声明变量未给值,默认值就是undefined.。
1.4.2 通过修改数组索引新增数组元素
- 可以通过修改数组索引的方式追加数组元素
- 不能直接给数组名赋值,否则会覆盖掉以前的数据
var arr =['red','green' ,'blue', 'pink' ];
arr[arr.length]= 'hotpink' ;
console.log(arr);
1.5 数组案例
1.要求︰将数组[2,0,6,1,77,0,52,0,25,7]中的0去掉后,形成一个不包含0的新数组。
var arr =[2,0,6,1,77,0,52,0,25,7];
var newArr = [];
for (var i = 0; i <arr.length - 1; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
}
}
2.翻转数组
要求:将数组[‘red’ , ’ green’, ‘blue’ , ‘pink’, ‘purple’]的内容反过来存放。输出:[‘purple" , ’ pink’ , “blue” , ’ green’ , "red”]
var arr = ['red' , ' green', 'blue' , 'pink', 'purple'];
var newArr = [];
for (var i = arr.length - 1; i > = 0; i--) {
newArr[newArr.length] = arr[i];
}
3.数组排序(冒泡排序)
冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。
var arr = [12,7,9,1,0,4];
console.log(arr.length);
var temp;
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]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
- 内层 for 循环,控制的是每一趟中交换对比的次数,应该是本次需要排序的个数 - 1。由于要从左至右排序。故内层 for 循环的计数器,应从0开始计数,对比 arr[0] 和 arr[1],…,arr[arr.length-2] 和 arr[arr.length - 1]。
- -外层 for 循环,控制的是排序的趟数,应该是 arr.length (元素个数) -1。从0开始计数的话,则应设置< 元素个数 - 1。
2.JavaScript 函数
2.1 函数的概念
在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。
虽然 for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS中的函数。
函数︰就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。
2.2 函数的使用
函数的使用分为两步:声明函数 和调用函数。
2.2.1 函数的2种声明方式
1.利用函数关键字自定义函数(命名函数)
//声明函数
function 函数名() {
//函数体
}
- function 声明函数的关键字,必须全部小写
- 函数一般是为了实现某个功能定义的,所以通常我们将函数名命名为动词,比如sayHi
// 1.利用函数关键字自定义函数(命名函数)
function fn() {
}
// 调用语句
fn();
2.函数表达式(匿名函数)
- 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
- 函数没有名字,此处的 fun 为变量名,而不是函数名
- 函数表达式也可以传递参数
// 2.函数表达式(匿名函数)
// var 变量名 = function() {};
var fun = function() {
console.log('我是函数表达式");
}
// 调用语句
fun();
2.2.2 调用函数
//函数名();
sayHi();//通过调用函数名来执行函数体代码
- 调用函数的时候千万不要忘记加小括号
- 口诀:函数不调用,自己不执行。
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
2.2.3 函数的封装
- 函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
- 简单理解:封装类似于将电脑配件整合组装到机箱中(类似快递打包)
2.3 函数的参数
2.3.1 形参和实参
在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参;而在调用该函数时,同样也需要传递相应的参数,这些参数被称为实参。
参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。
注意点:
- 多个参数之间用逗号隔开
- 形参可以看做是不用声明的变量
2.3.2 函数形参和实参个数不匹配问题
// 函数形参实参个数匹配
function getsum(num1,num2){
console.log(num1 + num2);
}
// 1.如果实参的个数和形参的个数一致,则正常输出结果
getSum(1, 2);
// 2.如果实参的个数多于形参的个数,会取到形参的个数
getsum(1, 2, 3);
// 3.如果实参的个数小于形参的个数,多余的形参定义为 undefined,最终的结果:1 + undefined = NaN
// 形参可以看做是不用声明的变量, num2 是一个变量但是没有接受值,结果就是undefined
getsum(1);
注意:在JavaScript中,形参的默认值是 undefined。
2.3.3 小结
- 函数可以带参数也可以不带参数
- 声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
- 调用函数的时候,函数名括号里面的是实参
- 多个参数中间用逗号分隔
- 形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
2.4 函数的返回值
2.4.1 return 语句
有的时候,我们会希望函数将值返回给调用者,此时通过使用return语句就可以实现。
2.4.2 return 终止函数
return语句之后的代码不被执行。
2.4.3 函数没有 return 返回 undefined
函数都是有返回值的:
- 如果有return,则返回return后面的值
- 如果没有return,则返回undefined
2.4.3 break,continue,return 的区别
- break :结束当前的循环体(如for、while )
- continue :跳出本次循环,继续执行下次循环(如for、while )
- return :不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码。
2.5 arguments 的使用
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
- 具有length属性
- 按索引方式储存数据
- 不具有数组的push , pop等方法
<script>
// arguments 的使用
function fn() {
console.log(arguments);// 里面存储了所有传递过来的实参
console.log(arguments.length);
console.log(arguments[0]);
}
fn(1,2,3);
</script>
控制台输出的 arguments 如下图:
注意:只有函数才有 arguments 对象,而且是每个函数都内置好了这个对象。
2.6 函数可以调用另外一个函数
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。
<script>
//函数是可以相互调用的
function fn1() i
console.log(11);
fn2();// 在fn1 函数里面调用了fn2
}
fn1();
function fn2(){
console.log(22);
}
</script>
3 JavaScript 作用域
3.1 作用域
1.1作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高护程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
简单来说,就是代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性,更重要的是减少命名冲突。
JavaScript 的作用域(es6)之前分为:
全局作用域 局部作用域
全局作用域:
整个script 标签 或者是一个单独的js文件
局部作用域(函数作用域):
在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
3.2 变量的作用域
根据作用域的不同,变量分为全局变量和局部变量。
3.2.1 全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
- 全局变量在代码的任何位置都可以使用
- 在全局作用域下var 声明的变量是全局变量
- 特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)
// 1.全局变量:在全局作用域下的变量在全局下都可以使用
var num = 10; // num就是一个全局变量
console.log(num); // 打印10
function fn() {
console.log(num);// 打印10
}
fn();
注意:在函数内部,没有声明直接赋值的变量也属于全局变量。
3.2.2 局部变量
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
- 局部变量只能在该函数内部使用
- 在函数内部var声明的变量是局部变量
- 函数的形参实际上就是局部变量
// 2.局部变量 在局部作用域下的变量 在函数内部的变量就是局部变量
function fun() {
var num1 = 10; // num1就是局部变量只能在函数内部使用
}
fun();
console.log(num1);// 报错 num1 is not defined
注意:函数的形参也可以看作是局部变量。
3.2.3 全局变量和局部变量的区别
- 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
- 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间
3.2.4 现阶段在js中没有块级作用域
- 现阶段我们js 没有块级作用域,js的作用域:全局作用域、局部作用域。
- 我们js 也是在es6的时候新增的块级作用域
- 块级作用域{} if {} for {}
// java语言的以下代码,{}外面的是不能调用num的
if(){
int num = 10;
}
// JavaScript语言的以下代码,{}外面的是能调用num的
if(3< 5){
var num = 10;
console.log(num);
3.3 作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
如果本层没有该变量的值,找离该变量最近的上层,简单来说就是: 就近原则
var num = 456;
function f1() {//外部函数
var num = 123;
function f2( {//内部函数
console.log(num); // 123
}
f2();
}
f1();
4 JavaScript 预解析
5 JavaScript 对象
5.1 对象
5.1.1 什么是对象?
在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的。
- 属性:事物的特征,在对象中用属性来表示(常用名词)
- 方法:事物的行为,在对象中用方法来表示(常用动词)
5.1.2 为什么需要对象?
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果要保存一个人的完整信息呢?
例如,将“张三疯”的个人的信息保存在数组中的方式为︰
var arr =[张三疯,‘男',,128,154];// 会带来歧义
JS中的对象表达结构更清晰,更强大。张三疯的个人信息在对象中的表达结构如下:
person.name =张三疯';
person.sex ='男';
person.age =128;
person.height = 154;
5.2 创建对象的三种方式
在JavaScript中,现阶段我们可以采用三种方式创建对象( object ) :
- 利用字面量创建对象
- 利用new Object创建对象
- 利用构造函数创建对象
5.2.1 利用字面量创建对象
对象字面量∶就是花括号(}里面包含了表达这个具体事物(对象)的属性和方法。
1.利用对象字面量创建对象{}
// var obj = {}; // 创建了一个空的对象
var obj = {
uname: ‘张三疯",
age: 18,
sex: '男',
sayHi: function() {
console.log( ' hi~');
}
}
- 里面的属性或者方法我们采取键值对的形式键属性名﹔值属性值
- 多个属性或者方法中间用逗号隔开的
- 方法冒号后面跟的是一个匿名函数
2.使用对象
调用对象的属性:
// 方法1.采取对象名.属性名的形式。理解为“的”
console.log(obj.uname);
// 方法2.对象名['属性名']的形式。注意方括号里面的属性必须加引号。
console.log(obj['age']);
调用对象的方法:
// 对象名.方法名()
obj.sayHi();
☆ 变量、属性、函数、方法
1.变量和属性:
相同点:
- 都是用来存储数据的
不同点:
- 变量:单独声明赋值,使用的时候直接写变量名,单独存在。
- 属性:对象里面的变量,不需要声明,使用的时候必须是 “对象.属性”形式,用来描述该对象的特征。
2.函数和方法:
相同点:
- 都是实现某种功能
不同点:
- 函数:单独存在,通过函数名()就可以调用的,
- 方法:对象里面的函数,方法不需要声明,使用“对象.方法”的形式调用,方法用来描述该对象的行为和功能。
5.2.2 利用new Object创建对象
跟我们前面学的 new Array() 原理一致,创建空的对象。
利用等号 “=” 赋值的方法,添加对象的属性和方法。
每个属性和方法之间用分号结束。
// 创建一个空的对象
var obj = new Object();
// 追加属性 uname
obj.uname = '';
// 追加方法
obj.sayHi = function(){
console.log('Hi~');
}
5.2.3 利用构造函数创建对象
前面两种方式一次只能创建一个对象,需要创建多个对象,且里面的很多属性和方法是相同的时候,可以使用构造函数创建对象。
构造函数里面封装的是对象。普通函数封装的是
构造函数︰是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
构造函数的语法格式:
function 构造函数名() {
this.属性名 = 值;
this.方法 = function() {}
}
// 调用构造方法
new 构造函数名();
- 通用规范:构造函数名的首字母必须大写。
- 构造函数不需要 return ,就可以返回结果。
- 调用构造函数必须使用 new 关键字。
- 只要 new 构造函数名() 就创建了一个对象。
- 构造函数内的属性和方法前面必须要添加 this。
举例:
// 构造函数
function Star(uname,age,sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(song){
console.log(song);
}
}
// 对象
var ldh = new Star('刘德华', 18, '男');
console.log(ldh.name);
ldh.sing('冰雨');
构造函数和对象
- 构造函数,如Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类( class )
- 创建对象,如new Stars(),特指某一个具体的事物,通过new关键字创建对象的过程我们也称为对象实例化
5.3 new 关键字
new 关键字执行过程:
- new 构造函数,在内存中创建了一个空的对象;
- this 指向刚才创建的空对象
- 执行构造函数里面的代码,给这个空对象添加属性和方法
- 返回这个对象
5.4 遍历对象属性
for…in语句用于对数组或者对象的属性进行循环操作。
//遍历对象
var obj = {
name: ' pink老师',
age: 18,
sex:‘男',
fn: function() {}
}
console.log(obj.name);
console.log(obj.age);
console.log(obj.sex);
// for in 遍历我们的对象
for(var k in obj){
console.log(k);// 输出属性名
console.log(obj[k]);// 输出属性值
}
JavaScript 内置对象
JavaScript中的对象分为3种:自定义对象、内置对象、浏览器对象
前面两种对象是JS基础内容,属于ECMAScript;第三个浏览器对象属于我们JS独有的,我们JS API讲解
内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
JavaScript提供了多个内置对象:Math、 Date . Array、String等
查文档
2.1 MDN
学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C来查询。
Mozilla开发者网络(MDN)提供了有关开放网络技术(Open Web )的信息,包括HTML、CSS和万维网及HTML5应用的API。
MDN: https://developer.mozilla.org/zh-CN/
2.2如何学习对象中的方法
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
Math 对象
// Math数学对象不是一个构造函数﹐所以我们不需要new来调用而是直接使用里面的属性和方法即可
console.log(Math.PI);
利用对象封装自己的数学对象,有PI属性和获取最大值和最小值的方法。
在这里插入代码片
4.1 Date 概述
- Date对象和Math对象不一样,他是一个构造函数,所以我们需要实例化后才能使用
- Date实例用来处理曰期和时间
4.2 Date()方法的使用
1.获取当前时间必须实例化
var now = new Date() ;
console. log (now) ;
2.Date()构造函数的参数
如果括号里面有时间,就返回参数里面的时间。例义日期格式字符串为‘2019-5-1’,可以写成new Date(‘2019-5-1’)或者new Date(‘2019/5/1’)