类型系统这里和Java差距较大
// Array 的 A 要大写
let arr = new Array();
[]
就表示一个空的数组let arr = [];
//创建数组的时候,同时指定初始值~
let arr2 = [1, 2, 'haha', false]; // 数组中保存的内容称为 "元素"
和java
不同,js
的数组长度是可以动态变化的,js
的数组更接近于java
的 ArrayList
~
js
的数组允许里面里面存在不同类型的元素!!
而Java
则要求务必是相同类型~
js
这种情况也是要 归咎于 动态类型 体系 ~
其他的动态类型的语言(Python,PHP,Ruby…)也都是类似的设定
但是这种设定并不是很好~
访问数组元素,通过取下标的方式来进行操作~
下标从 0 开始进行计数~
<script>
let arr = ['欸嘿', '哇哦', '嘻嘻'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
arr[2] = '哭哭';
console.log(arr);
console.log(arr.length)
</script>
使用下标的时候,最典型的场景,下标访问越界~~
在Java
中下标访问越界,抛出异常 ArrayIndexOutOfRangeExecption
在js
中打印一个下标访问越界的值,会打印undefined
表示一个"未被定义"的值,这是一个非法的结果
💌在这个越界的位置赋值:
虽然数组上本来没有下标为3
的位置,但是这个操作就会触发一个 插入 的行为,就把新元素给放到了对应下标的位置上了,整体就变成了长度为4的数组~
arr[100]
赋值操作,就会把下标为100
的元素给插入过去,整个数组长度变成了101
,中间的部分,都是empty(undefined)
;
观察下标,发现往下标为-1
处赋值效果和刚才100
还不一样,数组的整体长度没变,但是确实是把 “唧唧复唧唧” 这个元素给插入进来了
再往arr
中放入一个arr['阿巴阿巴'] = 'Dada';
:
发现可以把arr['阿巴阿巴'] = 'Dada'
当成键值对,js
的数组,还能起到map
的效果!!
把数组视为一个对象,js
的对象和Java
的对象不同,js
的对象是可以在运行时随意的新增属性的~~
阿巴阿巴
就是js
这个数组对象的成员了,js
中访问成员,既可以使用.
也可以使用[]
对于js
数组来说,[]
里是非负整数的时候,此时才把这个操作视为是"操作下标",如果是其他类型的值,都认为是数组的自定义属性~
虽然数组有能力表示键值对,但不建议这样用,js
里有专门的map
类型来表示键值对,(ES6标准里引入的特性)
有很多种方式,最常用的就是使用push
方法(类似ArrayList
,最常用的是add
方法),进行尾插,pop
进行尾删
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let arr = [];
for(let i = 0;i<10;i++) {
arr.push(i);
}
console.log(arr);
let ret = arr.pop();
console.log(ret);
console.log(arr);
</script>
</body>
</html>
js
的数组也支持中间位置的插入和删除
splice
既可以进行中间位置的插入,也可以进行中间位置的删除,还可以进行元素的替换
splice
功能是 “替换”,取数组上的一段,把这一段给替换成新的内容
这里由于没有指定新的元素,相当于"删除"操作了~
函数(functiion
)就是方法(method
),方法就是函数,只是不同叫法而已
通常情况下,不区分函数和方法的区别
如果非要深究的话,函数就相当于是独立的一段逻辑~ (不依附对象的)
方法则是依赖一个对象(本质上就是编译器在编译的时候,自动给方法前面多加个函数,然后自动把this
传进去)
举个例子:
//写到这里,仍然不清楚是返回什么类型
//返回的类型取决于x+y的类型,取决于x和y的类型
function add(x,y) {
return x+y;
}
let a = add(1,2);
console.log(a);
js
的函数,天然支持不同类型的参数!!
正因为js
是动态类型,调用函数,传参的时候,同一个函数就允许传不同的类型,只要传的这些类型,在函数内部能够正常使用即可!!
像js
这样的动态类型的语言,相当于自带了 “泛型” 机制~~ ,也不需要函数重载这样的语法 ~
js
的函数,同样是一个函数,就能支持不同个数的参数!!
js
并不强制要求,形参和实参个数匹配!
js
调用函数的时候,实参的个数可以比形参多,也可以比形参少,不会出现语法错误
当实参比形参多的时候,多出来的实参就不能通过形参获取到了
当实参比形参少的时候,多出来的实参就是undefined
解决上述问题,直接使用内置变量,arguments
,arguments
是数组,数组里放了调用函数时所有的实参~
arguments
这个数组就包含了调用add
方法的所有实参的值!!
❓ 为啥splice
这个方法就可以支持多个变长的参数?
就是通过arguments
完成的!!
在js
中,函数是可以像不同的变量一样进行赋值的,还可以作为另一个函数的参数,或者是另一个函数的返回值。
函数在js
中是"一等公民",这个函数就是和普通的变量一模一样~
function(){}
是定义了一个匿名的函数(没有名字),其实就是lambda
表达式~
js
里,代码中尝试访问一个变量,会首先查找当前的代码块,如果当前代码块中没有,就会继续往上级代码块中查找,一直查找到全局的作用域~ ( 标签这一级)
一个html
里可以有多个script
标签,此时这些标签的全局作用域是同一个!!
js
把上述变量作用域,查找规则,称为"作用域链"
js
的对象类似于Java
的对象,功能更加简化~
js
中的对象,是使用{ }
来表示的
对象中可以有属性,也可以有方法~
定义好对象,就可以使用 .
(成员访问运算符)来访问了~
js
对象定义的语法格式,非常像json
(只不过json
里面只有属性,没有方法)
在JS
中创建一个对象,不需要先创建一个类,JS
中也不是没有类这个概念(ES6版本的语法才加入)
JS
写构造函数,习惯上首字母大写,但小写也可以~
构造函数,会用到this
,同时不必写return
语句
这里的this
就表示即将构造出来的对象
使用构造函数来代替了Java
中的类,起到了"对象图纸"这样的效果~
在
ES6
标准以后,也引入了class
关键字,也就允许js
中定义"类"了~
这种构造函数的写法,了解就行,重点放在{ }
创建对象的方法上
在JS
里,虽然有类的概念,但是不能提供"封装",也不能进行"继承" (可以通过原型链的机制模拟实现出类似于继承的效果),更不能"多态"
所以JS并不是一个"面向对象"的编程语言!!!