数组的概念:
可以把一组相关数据一起存放,并提供方便的获取方式
什么是数组:
数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。
//普通变量一次只能存储一个值
var num = 10;
//数组一次可以存储多个值
var arr = [1,2,3,4,5];
JavaScript中创建数组有两种方式:
var 数组名 = new Array();
var arr = new Array();//创建一个空的新数组
//1.使用数组字面量方式创建空的数组
var 数组名 = [];
//2.使用数组字面量方式创建带初始值的数组
var 数组名 = [‘小白’,‘小黑’,‘大黄’];
声明数组并赋值我们称为数组的初始化
数组中可以存放任意的数据类型,例如:字符串,数字,布尔值等
索引(下标):用来访问数组元素的序号数组下标从0开始
数组可以通过索引来访问,设置,修改对应的数组元素,我们可以通过数组名[索引]的形式来获取数组中的元素。这里的访问就是获取的意思
//定义数组
var arr = [1,2,3];
//获取数组中的第二个元素
alert(arr[1]);//下标是从0开始
遍历:把数组中的每个元素从头到尾都访问一遍
//遍历1,2,3
var arr = [1,2,3];
for(var i = 0; i < 3; i++){
console.log(arr[i]);
}
//因为数组索引号从0开始,所以i必须从0开始
for循环里面的i是计数器,当索引号使用,arr[i]是数组元素第i个数组元素
数组长度
★求数组中的最大值:
//求数组中的最大值
//1.初始化arr[2,6,1,77,52,25,7]
//2.声明最大值max,默认最大值可以取数组中的第一个元素
//3.遍历数组for 寻找比当前max里大的值
//4.如果遍历的元素大于max,将这个元素存到max里面
var arr = [2,6,1,77,52,25,7];
var max = arr[0];
for (var i = 0; i <arr.length; i++){
if(arr[i]>max){
max = arr[i];
}
}
console. log(max);
可以通过修改length长度以及索引号增加数组元素
1.可以通过修改length长度
var arr = [1,2,3 ];
arr.length = 5; //将数组中元素增加到5
2.修改索引号
var arr = [1,2,3 ];
arr[3] = 'pink;'//追加数组元素
★翻转数组:
//翻转数组 [1,2,3,4,5] -> [5,4,3,2,1]
var arr = [1, 2, 3, 4, 5];
var i = 0;
var j = arr.length - 1;
while (i<=j){
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
console.log(arr);
★筛选数组:
//将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组中
// 方法一:
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);
// 方法二
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的新数组
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);
// 冒泡排序
var arr = [1,2,3,4,5];
for (var i = 1; i <= arr.length - 1; i++) {//依次循环四趟
for (var j = 0; j <= arr.length - i - 1; j++) {//每个元素比较4次并且比较完的不再比较
if (arr[j] > arr[j + 1]) {//前一个元素大于后一个元素
var temp = arr[j];//用中间变量交换
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
函数就是一段封装了一段可以重复执行调用的代码块 目的:就是让大量代码重复使用
1.声明函数
function 函数名(){
函数体
}
♦ function声明函数的关键字 全部小写
♦ 函数是做某件事函数名一般是动词
♦ 函数必须调用否则不能执行
2.调用函数
函数名()
♦ 调用函数必须加小括号
1.利用函数关键字自定义函数(命名函数)
function 函数名(){
函数体
}
function();
2.函数表达式(匿名函数)
var 变量名 = function(){};
var fun = function(are) {
console.log('我是函数表达式');
console.log(are);
}
fun('我是美女');
注意:
(1) fun是变量名 不是函数名
(2)函数表达式声明方式跟声明变量差不多,只不过声明变量里面存的是值
(3)函数表达式也可以进行传递参数
函数的封装:是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的接口
可以利用函数的参数实现函数重复不同的代码
function 函数名(形参1,形参2.....){ }//在声明函数的小括号里是形参(形式的参数)
函数名(实参1,实参2.....);//实际的参数
形参是接收实参的,相当于一个变量
参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去
形参可以看做是不用声明的变量
形参和实参个数不匹配的问题:
函数返回值的格式:
function 函数名(){
return 需要返回的结果;
}
函数名();
只要函数遇到return 就把后面的结果返回给函数调用者
函数名()=return后面的结果
★函数返回值的练习:
// 利用函数求数组中最大的数[5,2,99,101,67,77]
function getMax(arr){
// 首先定义个新数组Max[]放arr数组里的第0个元素
var max = arr[0];
// 因为Max已经指向第0个元素,所以i指向第一个元素
for ( var i = 1; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
// 函数名() = return后面的值
var re = getMax([5,2,99,101,67,77]);
console.log(re);
// 利用函数求数组中第二大的数[5,2,99,101,67,77]
function getMax(arr) {
var max = 0;
var max2 = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < max && arr[i] > max2) {
max2 = arr[i]
}
}
return max2;
}
// 函数名() = return后面的值
var re = getMax([5, 2, 99, 101, 67, 77]);
console.log(re);
函数返回值注意事项
1.return 终止函数,后面的代码不会被执行
2.return 只能返回一个值 返回的结果是最后一个值
3.如果函数没有return返回的结果是undefined
三者区别:
当我们不确定有多少个参数传递的时候,可以用argument来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有一下特点:
函数使用案例:
// 利用函数翻转任意数组
function flit(arr) {
var arr2 = [];
for (var i = arr.length - 1; i >= 0; i--) {
arr2[arr2.length] = arr[i];
}
return arr2;
}
var re = flit([5, 6, 7, 8]);
console.log(re);
// 利用函数冒泡排序由小到大排
function sort(arr) {
for (var i = 1; i <= arr.length - 1; i++) {
for (var j = 0; j <= arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var tep = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tep;
}
}
}
return arr;
}
var re = sort([68, 11, 6, 34, 25]);
console.log(re);
// 输入一个年份判断是否是闰年
function getYear(year) {
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(getYear(2004));
//用户输入一个年份判断是否是闰年,这里用了函数之间的调用
function outputYear() {
var year = prompt('请输入年份');
if (getYear(year)) {
alert('是闰年');
} else {
alert('不是闰年');
}
}
outputYear();
function getYear(year) {
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(getYear(2004));
定义:通过new函数名 来实例化对象的函数叫构造函数。任何的函数都可以作为构造函数存在。
构造函数的执行流程:
1.立刻创建一个新的对象
2.将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
3.逐行执行函数的代码
4.将新建的对象作为返回值返回
什么是作用域:
就是代码名字在某个范围内起作用和效果 目的是为了提高程序的可靠性 更重要的是减少命名冲突
js的作用域(es6)之前: 全局作用域 局部作用域
全局作用域: 整个script标签 或者是一个单独的js文件
注意: 如果在函数内部 没有声明直接赋值的变量也属于全局变量
局部作用域(函数作用域): 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
注意:函数的形参也可以看作是局部变量
<script>
// 全局作用域
var num = 10;
function fn() {
// 局部作用域
var num = 20;
}
</script>
从执行效果来看:
全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间
作用域链:
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值这种结构我们称之为作用域链 就近原则
站在目标出发。一层一层往外找
JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行
预解析:
预解析js引擎会把js里面所有的var还有function提升到当前作用域的最前面
代码执行:
按照代码书写顺序从上到下执行
预解析分为:
变量预解析(变量提升)和 函数预解析(函数提升)
变量提升 就是把所有的变量声明提升到当前作用域最前面 不提升赋值操作
// 预解析案例
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();
function f1() {
var a;
a = b = c =9;//b,c直接赋值没有var声明 当全局变量看
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
f1();
console.log(a);//报错
console.log(b);//9
console.log(c);//9
将声明函数提升到最前面 再提升函数里的(同样操作)
在JavaScript中,对象是一组无序的相关属性和方法 的集合,所有的事务都是对象,例如字符串、数值、数组、函数等
对象字面量:就是{ }花括号里面包含了表达这个具体事务的(对象)的属性和方法
注意:
(1) 里面的属性或者方法我们采取键值对的形式 键 属性名: 值 属性值
(2) 多个属性或者方法中间用逗号隔开
(3) 方法冒号后面跟的是一个匿名函数
var obj = {};//创建一个空对象
var obj = {
name:'张三',
age :18,
sex :'男',
fn : function(){
console.log('你好');
}
}
使用对象
调用对象属性我们采取 对象名.属性名
console.log(obj.name);
调用属性还有一种方法 对象名[‘属性名’]
console.log(obj['age']);
调用对象的方法:对象名。方法名 注意千万要加()
obj.fn();
//利用new Object创建对象
var obj = new Object();//创建一个空对象
obj.name = '娜娜';
obj.sex = '女';
obj.age = 18;
obj.skill = function(){
console.log('唱歌');
}
console.log(obj.name);
}
构造函数: 是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面
构造函数的语法格式:
function 构造函数名(){
this.属性 = 值;
this.方法 = function(){}
}
new 构造函数名();//调用构造函数
注意:
(1)构造函数名字首字母要大写
(2)构造函数不需要return 就可以返回结果
(3)调用构造函数必须使用new
(4)属性方法前面必须有this
//利用构造函数创建对象案例
function Hero(uname, type, blood){
this.name = uname;
this.type = type;
this.blood = blood;
this.attack = function(at){
console.log(at);
}
}
var lianpo = new Hero('廉颇','力量型','500血量');
console.log(lianpo);
var houyi = new Hero('后裔','射手型','300血量');
console.log(houyi);
lianpo.attack('近战');
houyi.attack('远战');
new关键字执行过程:
(1)在内存中创建一个空对象
(2)让this指向这个新的对象
(3)执行构造函数里面的代码。给这个新对象添加属性和方法
(4)返回这个新对象(所以构造函数里面不需要return)
利用for (变量 In 对象){}
// 利用遍历可以把对象里面的属性全部输出
var obj = {
name: '美女',
age: 18,
sex: '女'
}
for (var k in obj) {
console.log(obj[k]);
}
案例一:
// 利用对象封装自己的数学对象 里面有PI 最大值和最小值
var myMath = {
PI: 3.14159,
max:function(){
var max = arguments[0];
for (var i = 1; i < arguments.length-1; i++ ){
if(arguments[i] > max){
max = arguments[i];
}
}
return max;
}, //★不要忘记加逗号
min:function(){
var min = arguments[0];
for (var i = 1; i < arguments.length-1; i++ ){
if(arguments[i] > min){
min = arguments[i];
}
}
return min;
}
// Math对象随机数方法随机生成数1~10之间 用Math.random()内置对象
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
var re = getRandomIntInclusive(1, 10);
while(true){//死循环
var num = prompt('请输入一个数字');
if(num > re){
alert('数字大了');
}else if(num < re){
alert('数字小了');
}else{
alert('你猜对了');
break;
}
}
是一个构造函数必须使用new
(1)使用Date 如果没有参数返回当前参数
var date = new Date();
console.log(date);
(1)创建数组的两种方式:
// 1.利用数组字面量
var arr = [1,2,3];
console.log(arr[0]);
// 2.利用new Array()
var arr1 = new Array();//创建了一个空数组
var arr1 = new Array(2);//2表示 数组长度为2 里面有两个空的数组元素
var arr1 = new Array(2,3);//等价于[2,3]这样写里面有两个数组元素 是2和3
console.log(arr1);
(2)检测是否为数组
// 检测是否为数组
// (1)instanceof 运算符
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
// (2)Array.isArray(参数);
console.log(Array,isArray(arr));
console.log(Array,isArray(obj));
(3) 添加删除数组元素方法
// 1.push在我们末尾添加一个或者多个数组元素
var arr = [1,2,34];
arr.push(4,'美女');//直接添加了数组元素
console.log(arr.push(4,'美女'));//返回新数组的长度
console.log(arr);
// 2.unshift在数组的开头添加
arr.unshift(9,1);//直接写数组元素
console.log(arr);
(4) 删除数组元素
// pop删除数组的最后一个元素
var arr = [1,2,3];
console.log(arr.pop());//pop没有参数,一次只能删除一个元素,返回的是删除的那个元素
console.log(arr);
// shift删除数组的第一个元素
console.log(arr.shift());//shift和pop一样,删除数组的第一个元素
案例:
// 有一个包含工资的数组[1500,1200,2000,2100,1800],要求把数组中工资超过2000的删除,剩余的放到新数组里
var arr = [1500, 1200, 2000, 2100, 1800];
var newArray = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < 2000) {
//newArray[newArray.length] = arr[i];以前的写法
newArray.push(arr[i]);//现在学会了Push之后的写法
}
}
console.log(newArray);
// 数组排序
// 1.翻转数组
var arr = [1,2,3];
arr.reverse();
console.log(arr);
// 2.数组排序(冒泡排序)
var arr1 = [1,2,3];
arr1.sort(function(a,b){
return a-b;
});
console.log(arr1);
// 封装一个去重的函数unique要求去除数组中重复的元素
function unique(arr){
var newArr = [];//定义一个空的数组
for(var i = 0 ;i < arr.length; i++){
if(newArr.indexOf(arr[i]) === -1){//indexOf的意思是查找newArr里面是否有arr[i]这个元素,等于-1没有
newArr.push(arr[i]);//就向新数组里存入这个元素
}
}
return newArr;
}
var demo = unique(['c','b','b','a','c','b']);
数组转换为字符串
(6) 字符串对象
JavaScript还提供了三个特殊的引用数据类型:String、Number和Boolean
基本包装类型就是把简单的数据类型包装成为复杂数据类型,这样数据类型就有了属性和方法
// 基本包装类型
var str = 'andy';
console.log(str.length);
// 对象才有 属性和方法 复杂数据类型才有属性和方法
// 简单数据类型为什么会有length属性呢?
// 基本包装类型: 就是把简单数据类型包装成 复杂数据类型
// (1)把简单数据类型包装为复杂数据类型
var temp = new String('andy');
// (2)把临时变量的值 给str
str = temp;
// (3)销毁这个临时变量
temp = null;
字符串所有的方法,都不会修改字符串本身(字符串本身是不可变的),操作完成会返回一个新的字符串
// 字符串对象,根据字符返回位置 str.indexOf('要查找的字符',[起始的位置])
var str = '我是美女';
console.log(str.indexOf('美'));
console.log(str.indexOf('美',1));//从索引号第一个开始查找
// 查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
var str = "abcoefoxyozzopp";
var f = str.indexOf('o');
var num =0 ;
while (f !== -1){
console.log(f);
num++;
f = str.indexOf('o',f + 1);
}
console.log("出现的次数"+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));
// 3.str[index]H5新增
console.log(str[0]);
// 有一个对象 来判断是否有该属性 对象['属性名']
var a = {
age: 18
}
if(a['age']){
console.log('里面有该属性');
}else{
console.log('没有该属性');
}
// 判断一个字符串'abcoefoxyozzopp'中出现次数最多的字符,并统计其次数
var o = {};
var str = 'abcoefoxyozzopp';
for(var i = 0; i < str.length; i++){
var chars = str.charAt(i);
if(o[chars]){//o[chars]得到的是属性值
o[chars]++;
}else{
o[chars] = 1;
}
}
console.log(o);
// 遍历对象
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);