前端学习记录 —— JavaScript(二)

本文详细介绍了JavaScript中的数组操作,包括创建、访问、遍历及新增元素,接着讲解了函数的定义方式、参数使用及作用,并对比了break、continue和return的差异。此外,还探讨了JavaScript的作用域概念以及预解析机制,包括变量和函数的提升。通过实例深入理解JavaScript的基础语法。
摘要由CSDN通过智能技术生成

前言

本文主要介绍 JavaScript 数组、函数、预解析内容

一、数组

数组的概念

一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。

创建数组的两种方式

1. 利用new 创建数组

var 数组名 = new Array([n]);//[]代表可选 若写n,则代表数组的长度
var arr = new Array();//创建了一个名为 arr 的空数组

2. 利用数组字面量创建数组 []
// 1. 使用数组字面量方式创建空的数组
var 数组名 = [];//若写n,则代表数组的长度
    
//2. 使用数组字面量方式创建带初始值的数组
//3. 声明数组并赋值称为数组的初始化
var arr =['1','2','3','4'];
var arr2 = ['fan',true,17.5];//数组中可以存放任意类型的数据
3. 访问数组元素

索引(下标):用来访问数组元素的序号。索引从 0 开始

<script>
        // 1.数组(Array) :就是一组数据的集合 存储在单个变量下的优雅方式 
        // 2. 利用new 创建数组
        var arr = new Array(); // 创建了一个空的数组
        // 3. 利用数组字面量创建数组 []
        var arr = []; // 创建了一个空的数组
        var arr1 = [1, 2, '老师', true];
        // 4. 我们数组里面的数据一定用逗号分隔
        // 5. 数组里面的数据 比如1,2, 我们称为数组元素
        // 6. 获取数组元素  格式 数组名[索引号]  索引号从 0开始 
        console.log(arr1);
        console.log(arr1[2]); // pink老师
        console.log(arr1[3]); // true
        var arr2 = ['迪丽热巴', '古丽扎娜', '佟丽丫丫'];
        console.log(arr2[0]);
        console.log(arr2[1]);
        console.log(arr2[2]);
        console.log(arr2[3]); // 因为没有这个数组元素 所以输出的结果是 undefined
</script>
4. 遍历数组

数组长度: 数组名.length

求数组[2,6,1,77,52,25,7]中的最大值

<script>
        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);
</script>
5. 新增数组元素

数组[数组.length] = 新数据;

// 1. 数组[数组.length] = 新数据;
arr = [] //arr.length = 0;
for (var i = 0; i < 10; i++) {
  arr[arr.length] = '0';
}
console.log(arr);
案例

筛选数组 大于10的元素选出来放到新数组中

注意技巧:

<script>
        // 将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组。
        // 1、声明一个新的数组用于存放新数据newArr。
        // 2、遍历原来的旧数组, 找出大于等于 10 的元素。
        // 3、依次追加给新数组 newArr。
        // 方法1
        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);
        // 方法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);
</script>

JS 中涉及数组的删除元素、翻转等可以使用内置对象的方法实现;详见:
https://blog.csdn.net/weixin_43848614/article/details/122334595

二、函数

1. 自定义函数方式(命名函数)

利用函数关键字 function 自定义函数方法

// 声明定义方式
function fn() {...}
// 调用 
fn(); 

因为有名字,所以也被称为命名函数
调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面

2. 函数表达式方式(匿名函数)

利用函数表达式方式的写法如下:

// 这是函数表达式写法,匿名函数后面跟分号结束
var fn = function(){...}// 调用的方式,函数调用必须写到函数体下面
fn();
  • 因为函数没有名字,所以也被称为匿名函数
  • 这个 fn 里面存储的是一个函数
  • 函数表达式方式原理跟声明变量方式是一致的
  • 函数调用的代码必须写到函数体后面
  • 如果函数没有 return ,返回的值是 undefine
  • return 只能返回一个值。如果用逗号隔开多个值,以最后一个为准
3. 函数的参数

形参:函数定义时候,传递的参数(实参值传递给形参,不用声明的变量);

实参:函数调用时候,传递的参数

//带参数的函数声明
function 函数名(形参1,形参2,形参3…) {
//函数体
}
// 带参数的函数调用
函数名(实参1,实参2,实参3…);

函数形参和实参数量不匹配时
参数个数说明
实参个数等于形参个数输出正确结果
实参个数多于形参个数只取到形参的个数
实参个数小于形参多的形参定义为undefined,结果为NaN
function getSum(a, b, c) {
  return a + b + c;
}
// js中形参的默认值是undefined。
// 调用函数
var n = getSum(1, 2);// n = NaN
var n = getSum(1, 2, 3, 4); //1 + 2 +3 = 6
4. break,continue,return的区别
  • break: 结束当前的循环体 (如for、while)
  • continue: 跳出本次循环,继续执行下次循环
  • return: 不仅可以退出(函数体内)循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码
//避免踩坑 return只能结束函数体内的代码
 function breakDown() {
   for (var i = 0; i < 10; i++) {
     if (i == 5) {
       return 1;
     }
   console.log(i);
   }
 }
 breakDown();
 
 //避免踩坑2 函数如果有return 则返回的是 return 后面的值;
 // return d,a,b; 返回的是b的值
 //如果函数没有 return语句,则返回undefined
5. arguments 的使用

当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。在 JavaScript 中,arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参

arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:

  • 具有 length 属性;
  • 按索引方式储存数据;
  • 不具有数组的 push , pop 等方法
<script>
        // 利用函数求任意个数的最大值
        function getMax() { // arguments = [1,2,3]
            var max = arguments[0];
            for (var i = 1; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(getMax(1, 2, 3));
        console.log(getMax(1, 2, 3, 4, 5));
        console.log(getMax(11, 2, 34, 444, 5, 100));
</script>

三、作用域

  • 作用域

一段程序代码中所用到的名字并不总是有效和可靠的,而限定这个名字的可用性代码范围就是这个名字的作用域。

作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
ES6之前作用域有两种 全局作用域和局部作用域(函数作用域)
  • 「全局作用域」

作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件。

  • 「局部作用域」

作用于函数内部的代码环境,就是局部作用域。因为跟函数有关系,所以也被称为函数作用域。

  • JS没有块级作用域

块作用域由 {} 包括

在其他编程语言,if语句中,循环语句创建的变量,仅仅只能在本if语句,本循环语句中使用,如下👇👇

if(true){
   int num = 123;
   System.out.print(num); //123
 }
 System.out.print(num);//报错

以上java代码会报错,因为代码中 {}是一块作用域,其中声明的变量num,在{}之外不能使用,而JavaScript代码则不会报错

Js中没有块级作用域 (在ES6之前); es6 新增作用域

if(true){
  var num = 123;
  console.log(num); // 123
}
console.log(num);// 123
变量的作用域

全局变量和局部变量的区别:

全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会销毁,因此比较占内存
局部变量:旨在函数内部使用,当其所在的代码块被执行时,才会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间。
作用域链

「作用域链」只要是代码都在一个作用域中,写在函数内部的局部作用域,未卸载仍和行数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;根据[内部函数可以访问外部函数变量] 的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链。

function f1() {
     var num = 123;
     
     function f2() {
         var num = 0;
         console.log(num); // 站在目标出发,一层一层的往外查找
     }
     f2();
 }
 var num = 456;
 f1();

运行结果:
0

在这里插入图片描述

作用域链:采取就近原则的方式来查找变量最终的值

var a = 1;
function fn1() {
    var a = 2;
    var b = '22';
    fn2();
    function fn2() {
        var a = 3;
        fn3();
        function fn3() {
            var a = 4;
            console.log(a); //a的值 4
            console.log(b); //b的值 '22'
        }
    }
}
fn1();

在这里插入图片描述

四、JS 预解析

「预解析相关概念」JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。

「预解析」在当前作用域下,JS代码执行之前,浏览器会默认把带有 var 和 function声明的变量在内存中进行提前声明或定义。

「代码执行」从上往下执行JS语句

预解析会把变量和函数的声明在代码执行之前完成,预解析也叫做变量、函数提升。

变量预解析(变量提升)

变量的声明会被提升到当前作用域的最上面,变量的赋值不提升。

console.log(num); // 结果是多少?
var num = 10; // ?
相当于
var num;
console.log(num);// 结果是 undefined //注意: 变量提升只提升声明,不提升赋值。
num = 10;

函数预解析(函数提升)

函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

fn();
function fn() {
    console.log('打印');
}

结果: 控制台打印字符串 — “打印”
注意: 函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!

函数表达式声明函数问题

函数表达式创建函数,会执行变量提升,此时接收函数的变量名无法正确的调用

fn();
var fn = function(){
  console.log("想不到吧");
}

结果: 报错提示 “fn is not a function”
解释: 该段代码执行之前,会做变量声明提升,fn 在提升之后的值是 undefined ;而 fn 调用是在 fn 被赋值为函数体之前,此时 fn 的值是 undefined,所以无法被调用。

  • 预解析案例1
var num = 10;
fun();

function fun(){
  console.log(num);
  var num = 20;
}

相当于执行了以下操作 结果打印 undefined
var num;

function fun(){
  var num;
  console.log(num);
  num = 20;
}
num = 10;
fun(); 
  • 预解析案例2
var a = 18;
f1();

function f1(){
  var b = 9;
  console.log(a);
  console.log(b);
  var a = '123';
}

相当于执行了以下操作 结果为 undefined 9
var a;
function f1(){
  var b;
  var a;
  b = 9;
  console.log(a);
  console.log(b);
  a = '123';  
}
a = 18;
f1();  
  • 预解析案例3
f1();
console.log(c);
console.log(b);
console.log(a);

function f1() {
  var a = b = c = 9;
  console.log(a);
  console.log(b);
  console.log(c);
}

相当于执行了以下操作 结果为 9 9 9 9 9 "报错--a is not defined"
function f1() {
  var a;
  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);
}
f1();
console.log(c);
console.log(b);
console.log(a);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何为xl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值