一、数组
1、概念
数据(Array)可以把一组相关的数据一起存放,并提供非常方便的访问(获取方式)。
数组是指一组数据的集合,其中每个数据被称作元素,在数组中可以存放任意类型的元素。
2、创建数组
2.1、利用new创建
var arr = new Array(); // 创建空数组
2.2、利用数组字面量创建数组
var arr = []; // 创建一个空数组
var arr1 = [1,'2',true] // 创建一个拥有不同数据类型元素的数组
3、获取数组元素
3.1、数组索引
-
索引(下标):用来访问数组元素的序号(数组下标从0开始)
-
数组可以通过索引来访问(获取)、设置、修改对应的数组元素
// 获取数组中元素:数组名[索引] var arr = [1,2,3] console.log(arr[2]) // 3。索引从0开始。 console.log(arr[3]) // undefined。数组没有第4个元素。
4、遍历数组
var arr = [1,2,3];
// arr.length:数组长度
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
5、新增元素
5.1、修改length
- 通过修改length长度来实现数组扩容的目的
- length属性是可读写的
var arr = [1,2,3]
arr.length = 5; // 把数组长度修改为5,里边有5个元素,后两个元素为undefined
5.2、修改索引号
var arr = [1,2,3]
arr[3] = 4 // 如果索引号未被占用,追加数组元素。此时arr=[1,2,3,4]
arr[0] = 4 // 如果索引号被占用,替换数组元素。此时arr=[4,2,3,4]
6、数据排序
6.1、冒泡排序
是一种算法,是一系列的数据按照一定的顺序进行排列显示(从小到大 或 从大到小)
// 编写方法,实现冒泡
var arr = [29,45,51,68,72,97];
//外层循环,控制趟数,每一次找到一个最大值
for (var i = 0; i < arr.length - 1; i++) {
// 内层循环,控制比较的次数,并且判断两个数的大小
for (var j = 0; j < arr.length - 1 - i; j++) {
// 白话解释:如果前面的数大,放到后面(当然是从小到大的冒泡排序)
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);//[2, 4, 5, 12, 31, 32, 45, 52, 78, 89]
二、函数
1、概念
函数就是封装了一段可以被重复执行调用的代码块。目的是让大量代码重复使用。
2、函数使用
2.1、声明函数
-
命名函数
// 函数构造格式 function 函数名(){ // 函数体 } // (1)function 声明函数的关键字 全部小写 // (2)函数是做某件事,函数名一般是动词 // (3)函数不调用 自己不执行
-
匿名函数
var 变量名 = function(){}
2.2、函数调用
// 声明函数
function sayHi(){
console.log('Hi!~')
}
// 调用函数:函数名()
sayHi()
3、函数的封装
函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
4、函数的参数
参数的作用:在函数内部某些值不能固定,可以通过参数在调用函数时传递不同的值进去
- 形参:声明函数的小括号里
- 实参:调用函数的小括号里
// 声明函数
function 函数名(形参1,形参2...){
}
// 调用函数
函数名(实参1,实参2...)
-
形参和实参不匹配问题
function getSum(a,b){ console.log(a+b); } // 如果实参个数和形参个数一致 getSum(1,2) // 3 正常输出结果 // 如果实参个数多于形参个数 getSum(1,2,3) // 3 会取形参的个数 // 如果实参个数小于形参的个数 getSum(1) // NaN 多余的形参定义为undefined。任意数字+undefined都不是一个数字
5、函数的返回值
5.1、return
function 函数名(){
return 需要返回的结果;
}
-
终止函数,return 后的代码不被执行
-
return只能返回一个值。如果返回多个值,以最后一个值为准
-
如果想返回多个值。可以利用数组存放值,返回数组
-
如果函数,有return返回return后的值;如果没有return则返回undefined
-
return可以退出循环,返回语句中的值,同时可以结束当前函数体内的代码
6、arguments
当我们不确定有多少个参数传递的时候,可以用arguments来获取
在JS中,arguments实际上它是当前函数的一个内置对象。
所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以遍历。
伪数组具有以下特点:
- 具有length属性
- 按索引方式存储数据
- 不具有数组的push,pop等方法
function fn(){
console.log(arguments)
}
fn(1,2,3)
三、作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
- 作用:
- 提高了程序逻辑的局部性
- 增强了程序的可靠性
- 减少了名字冲突
1、JS作用域(ES6之前)
- 全局作用域
- 整个script标签
- 单独一个JS文件
- 局部作用域
- 函数内部
2、变量的作用域
- 全局变量
- 全局作用域下的变量,全局下都可以使用
- 注:函数内部没有声明,直接赋值的变量也是全局变量
- 局部变量
- 局部作用域下的变量,只能在函数内部使用
- 注:函数的形参也可看做局部变量
- 区别
- 从执行效率看
- 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
- 局部变量当程序执行完毕就会销毁
- 从执行效率看
3、块级作用域
- if{} for{}的花括号中定义的变量外部可以使用
- 当前JS没有块级作用域的概念
- ES6新增块级作用域概念
4、作用域链
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链。
取值时,采用就近原则,会查找上一级,如果没有再查找上一级的上一级,一级一级查找
var num = 10;
function fn(){ // 外部函数
var num=20;
function fun(){
console.log(num) // 内部函数
}
}
四、预解析
1、预解析
// 问1
console.log(num) // 报错
// --------------------------
// 问2
console.log(num) // undefined 坑1 ==》 var num;
var num = 10; console.log(num)
// -------------------------- num = 10
// 问3
fn(); // 11
function fn(){
console.log(11)
}
fn(); // 11 上下都可以调用
// --------------------------
// 问4
fun() // 报错 坑2 ==》 var fun;
var fun = function(){ fun()
console.log(22) var fun = function(){console.log(22)}
}
fun() // 22
JavaScript代码是由浏览器中的JavaScript解释器来执行的。
JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行
- 预解析:JavaScript引擎会把JavaScript里所有的
var
和function
提升到当前作用域的最前边- 变量预解析(变量提升):将所有的变量声明提升到当前的作用域的最前边。注意不提升赋值。
- 函数预解析(函数提升):把所有的函数声明提升到当前作用域的最前边。注意不调用函数。
- 代码执行
- 按照代码书写的顺序从上往下执行
该内容学习自 传智播客JavaScript基础课程 javaScript零基础通关必备教程