前端学习(四十三) JavaScript-函数(javaScript)

概述

子程序是一个大型程序中的某部分代码,有一个或多个语句块组成,它负责完成某项特定任务,而且相较于其他代码,具备有独立性,一般会有输入参数和返回值,提供对过程的封装和细节的隐藏;

在JS中子程序被称作函数,也就是function,如果函数挂挂载在一个对象上,就称它为对象的方法

函数基础

使用关键字function定义,通常用2种方式:函数的声明语句函数的表达式

//函数声明

function sum(a,b){return a+b};//sum是函数名a,b是形参列表return a+b这个大括号里面的是函数体

//函数表达式

var a=function sum(a,b){return a+b};

通常函数都会包含一个return,如果没有return,那么返回值就是undefined

函数定义:构造函数的形式

第三种定义的方式是使用function构造函数,最后一个参数是函数体,之前的都是函数的形参

var sum=new function{"num1","num2","return num1+num2"}

函数调用

function sum(a,b){return a+b}

var x=sum(1,1)  //这边括号里的(1,1)是实参,和形参是一一对应的

console.log(x)  //2

函数参数

function sum(a,b=1){return a+b}

var x=sum(1,1) 

参数可以设定默认值,如果调用时没有传入对应的值,那么就会调用默认值,比如:

function sum(a,b = 1) {
    return a+b;
}
var a=sum(1);
console.log(a);  //a为2

函数内部属性

在函数内部,有两个特殊对象:arguments和this;

arguments:在函数体内,arguments表示实参列表对象,它是一个类数组,可以通过下标访问实参值,例如:

function sum() {
    return arguments[0]+arguments[1];
}
console.log(sum(1,2))

this:在函数体内,this是指函数执行的环境对象(也叫context),一般来说,this是指调用函数的对象,如果没有,就是全局对象,在浏览器中就是window对象

var a=function () {
    console.log(this);
}
a();  //输出window对象
var obj={
    a:function () {
        console.log(this)
    }
}
obj.a();  //输出obj

在js中,函数是一种特殊对象

函数是一种特殊的对象,意味着它也是一种值,所以函数可以当作参数传递,赋值变量,作为数组的元素等

function fa(a,b) {
    return a(b)
}
function sum(d) {
    return 1+d;
}
console.log(fa(sum,3));

函数是一种特殊的对象,那么也可以拥有属性和方法,函数有两个标准属性:length,name,方法有call,apply,bind

length:是该函数期望参数的个数,不包括默认值和剩余参数长度只计算到第一个参数默认参数或剩余参数前的位置,例如

function xa(a,mun=1,...mun2) { }
function xb(a,mun=1,num3,...mun2) { }
console.log(xa.length)  //1
console.log(xb.length)  //1

函数的name属性是该函数的名称,示例:

function sum1(d) {return 1+d;}
var obj={
    a:function () {}
}
var ac=new Function();

console.log(sum1.name);  //sum1
console.log(obj.a.name);  //a
console.log(ac.name);   //anonymous

第三个比较特殊,是一个匿名函数,所以属性名的输出为anonymous

下面的代码解释call(),apply(),bind()示例中,解决的同一个问题是:

1.如果用this.name获取到joy这个值

2.函数say如何接收更多的参数

call方法:调用函数,可以指定函数中的this和传参列表

var obj={
    name:"joy",
    say:function (content) {
        var say=function () {
            console.log(this.name+' say '+content)
        };
        say();
    }
};
obj.say("welcome");

上例中的打印this.name并没有打印出本对象中的name,因为如果没有指定的话this指的是全局的window的window并没有name这个属性,所以没有显示,所以要做如下显示,将say(),这个启用,改成say.call(this),指定了对象是obj对象,当然这个写法等同于say.call(obj),但是这种写法如果对象名改变了就需要重写修改,不如this来的方便

var obj={
    name:"joy",
    say:function (content) {
        var say=function () {
            console.log(this.name+' say '+content)
        };
        say.call(this);  //this改成obj也可以,但是可扩展性不高
    }
};
obj.say("welcome");

如果想传入更多的参数那么可以改成obj.say("welcome","school","name"),然后将say:function(content,a,b)这边修改

apply方法:调用函数,可以指定函数中的this和传入参数数组,注意,apply和call的区别在于传参call传的是参数列表,而apply传入的是数组

上例中,将

var obj={
    name:"joy",
    say:function (content,array) {
        var say=function () {
            console.log(this.name+' say '+content+array[0]+array[1])
        };
        say.apply(this);
    }
};
obj.say("welcome",[" a "," b "]);

call()方法和apply()方法没有实质的区别,唯一的区别是call传入的是参数列表,apply传入的是数组(记忆小技巧,apply和array都是a开头的,记住apply是数组)

bind()方法:生成一个新的函数,可以指定函数调用时的this对象和传参列表

var obj={
    name:"joy",
    say:function (content,a,b) {
        var say=function () {
            console.log(this.name+' say '+content)
        };
        say();
    }
};
obj.say("welcome");

bind()方法因为是生成了一个函数,因此,如下示例:

var obj={
    name:"joy",
    say:function (content,a,b) {
        var say=function () {
            console.log(this.name+' say '+content)
        };
        var say1=say.bind(this);   //需要新建一个say1,
        say1();
        console.log(say==say1);    //say和say1并不相等,说明不是一个函数
    }
};
obj.say("welcome");

传参数的方式和call相等用逗号隔开的参数

变量作用域简介

JS查找变量的过程:先查找局部作用域,再查找嵌套作用域(不一定有),再查找全局作用域,个人理解:还是就近查找,如果没有就往上一层查,一层一层往上;

在JS中作用域分为:局部作用域全局作用域局部作用域中的变量叫做局部变量全局作用域中的变量叫做全局变量

局部变量在每次执行函数的时候都会创建执行结束后销毁函数外不可访问

全局变量在所有代码中都可以访问和修改;

另外:局部变量中的变量名可以和全局变量中的相同,但是两者没有关系

在es6中引入了let,const,它们是声明块级作用域变量,块由{}组成

obj.say("welcome");
let x=10;
var y=10;
{
    let x=5;
    var y=5;
    {
        let x=2;
        var y=2;
        console.log(x+" "+y)    //2 2
    }
    console.log(x+" "+y);   //5 2
}
console.log(x+" "+y);   //10 2

这边的let因为是块级变量,所以相互不守干扰,但是y就不行,受到了最里层的定义影响

原型简介

对象除了自身的属性外,还可以从一个称为原型(prototype)的对象继承属性。原型式继承是JS的核心特征。

箭头函数

箭头函数表达式的语法比函数更加简短,并且不能绑定自己的this,arguments,super和new.target。这些函数表达式最合适

用于非方法函数,并且它们不能用作构造函数,如下示例:

var a=["qasdd","wasdd","asde","easd","r1ee"];
var x=a.map(function (a) {
    return a.length
});
    console.log(x)  //5 5 4 4 4
    var m=a.map((a) => {
        return a.length
        });
    console.log(m); //5 5 4 4 4
    var n=a.map(x=>x.length)
    console.log(n);  //5 5 4 4 4

猜你喜欢

转载自blog.csdn.net/zy21131437/article/details/81105873