欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript(函数与预解析)

程序员文章站 2022-07-04 20:05:48
...

JSday4

函数

函数:封装了一段可以被重复调用执行的代码块,通过此代码块可以实现大量代码的重复使用。

function getSum(num1,num2){
    var sum = 0;
    for(var i=num1; i<num2; i++){
        sum += i;
    }
    console.log(sum);
}
getSum(1,5);

函数的使用

声明函数、调用函数

函数的声明:

function 函数名(){
	// 函数体
}
// function声明函数的关键字 全部小写
// 函数是做某件事情,函数名一般是动词
// 函数不调用自己不执行

调用函数

函数名()

函数的封装

把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

函数的参数

形参、实参

function 函数名(形参1,形参2..){
	
}
函数名(实参1,实参2..)

函数形参和实参个数不匹配的问题

  • 若实参的个数和形参的个数一致,则正常输出结果
  • 若实参的个数多于形参的个数,会取到形参的个数
  • 若实参的个数小于形参的个数,多余的形参定义为undefined 最终的结果就是NaN
参数个数 说明
实参等于形参个数 正常输出
实参多余形参个数 只取到形参个数
实参小于形参个数 多余形参定义为undefined,结果为NaN

函数的return

函数将值返回给调用者,此时可以通过return语句实现

function 函数名(){
    return 需要返回的结果;
}
函数名();
// 函数只是实现某种功能,最终的结果需要返回给函数的调用者
// 只要函数遇到return 就把后面的结果返回给函数的调用者 函数名()=return
// 在实际开发中经常使用一个变量来接收函数的返回结果

例子:获取数组中最大的数字

function getMax(arr){
    var max = arr[0];
    for(i=0;i<arr.length;i++)
    {
        if(arr[i]>=max)
        {
            max = arr[i];
        }
    }
    return max;
}
console.log(getMax([1,2,7,4,5]));

return终止函数

  • return 后面的代码不会被执行

  • return只能返回一个值,如果用逗号隔开多个值,以最后一个为准

function getResult(num1,num2){
	return [num1+num2,num1-num2,num1*num2,num1/num2];
}
var re = getResult(1,2); //可以实现返回一个数组
console.log(re);

函数没有return返回undefined

  • 函数有return则返回return后面的值,若没有return则返回undefined

  • return 不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前函数体内的代码

arguments的使用

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

function fn(){
    console.log(arguments); // 里面存储了所有传递过来的实参
}

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

  • 具有length属性
  • 按索引的方式进行存储数据
  • 不具有数组的push,pop等方法
  • 只有函数才有arguments对象,每个函数都已内置了arguments对象

函数实例

  1. 利用arguments实现对任意数组的翻转
function reverseArr(){
    var tempArr = [];
    for(var i=arguments.length-1; i>=0; i--){
        tempArr[tempArr.length] = arguments[i];
    }
    return tempArr;
}
console.log(reverseArr(1,2,3,4,5));
  1. 利用函数封装,对数组进行排序–冒泡排序
function arrangeArr(arr){
    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])
            {
                var temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    return arr;
}
var rs = arrangeArr([1,5,2,3,5,9]);
console.log(rs);

函数的互相调用

实例:用户输入年份,输出当前年份的天数

function returnYear()
{
    var year1 = prompt('请输入想要判断的年份');
    if(judgeYear(year1))
    {
        alert("改年份为闰年,2月有29天");
    }else
    {
        alert("改年份是平年,2月有28天");
    }
}
function judgeYear(year)
{
    var flag = false;
    if(year%4==0 && year%100!=0 || year%400 ==0)
    {
        flag = true;
    }
    return flag;
}
returnYear();

函数的两种声明方式

  • 利用函数关键字自定义函数(命名函数)
function fn()
{
    // 函数体
}
  • 函数表达式声明函数(匿名函数,该函数并没有函数名)

调用必须写在声明下面

var fun = function()
{
    //函数体
}
fun()
// fun是变量名,不是函数名
// 函数表达式声明方式与声明变量差不多,变量中存储的是值,函数表达式中存的是函数
// 函数表达式也可以传递参数

JavaScript作用域

作用域

一段程序代码中所用到的名字并不总是有效可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突

==代码名字(变量)==在某个范围内起作用和效果 目的是为了提高程序的可靠性,减少命名冲突。

JS的作用域(es6之前)

  • 全局作用域

整个script标签 或者是单独的JS文件

  • 局部作用域(函数作用域)

在函数内部 即 代码名字只在函数内部起效果

变量的作用域

  • 全局变量

在全局作用域下的变量,在全局下均可使用。

注意 若在函数内部没有声明直接赋值的变量也属于全局变量

  • 局部变量

在局部作用域下的变量,在函数内部的变量。外部无法调用

注意 函数的形参也可以看做是局部变量

  • 从执行效率来看局部变量和全局变量

全局变量只有在浏览器关闭的时候才会销毁,比较占内存资源

局部变量当我们程序执行完毕就会销毁,比较节约内存资源

  • JS没有块级作用域

在es6时新增块级作用域

块级作用域{} if{} for{}

作用域链(就近原则)

  • 只要是代码,就至少有一个作用域

  • 写在函数内部的位局部作用域

  • 若函数内部还有函数,那么在这个作用域中就又诞生了一个作用域

  • 根据在内部函数可以访问外部函数变量的机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链。

JS的预解析

  • 预解析

JavaScript代码是由浏览器中的JavaScript解析器来执行的,JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行

预解析: js引擎会把js里所有的var 和 function提升到当前作用域的最前面

代码执行:按照代码书写顺序从上往下执行

  • 变量预解析(变量提升)和函数预解析(函数提升)

变量预解析:将所有的变量声明提升至当前作用域的最前面 不提升赋值操作

// 问题1
console.log(num);
var num = 10;
// 此时输出undefined

// 相当于执行了一下代码
var num; //变量提升,但不提升赋值操作
console.log(num);
num = 10;

函数预解析:

把所有的函数声明提升至当前作用域的最前面,不调用函数

  • 预解析案例
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

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
报错

// 此时解析相当于进行了以下操作

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);

JavaScript对象

对象

万物皆对象,对象是一个具体的事物

在JavaScript中,对象是一组无序的相关属性方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

对象是由属性方法组成的。

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)

创建对象的三种方式

三种创建对象(object)的方法:

  • 利用字面量创建对象

对象字面量: 就是==花括号{}==里面包含了表达这个具体事物(对象)的属性和方法。

var obj = {
    uname: 'lsq',
    age: '22',
    sex: '男',
    hello: function(){
        console.log('你好');
    }
}
// 里面属性或者方法采取键值对的方式 
// 多个属性或者方法中间用逗号隔开
// 方法冒号后面跟的是一个匿名函数

// 使用对象
// 调用对象的属性 采取对象名.属性名(obj.uname)
// 第二种调用属性的方法 对象名['属性名']

// 调用方法
// 对象名.方法名obj.hello()
  • 利用new Object创建对象

  • 利用构造函数创建对象

new关键字

遍历对象属性