Home >Web Front-end >JS Tutorial >Detailed explanation of JavaScript functions_javascript skills
A function is a set of statements that can be run anytime and anywhere. Functions are very important as the core of ECMAScript. A function is an event-driven or reusable block of code that executes when it is called. That is, a function is a piece of JavaScript code that is defined once but can be called or executed any number of times. Functions sometimes have parameters, which are local variables with values assigned when the function is called. Functions often use these parameters to calculate a return value, which also becomes the value of the function call expression.
1. Function declaration
Functions are a core concept for any language. Any number of statements can be encapsulated through functions, and they can be called and executed anywhere and at any time. Functions in JS are declared using the function keyword, followed by a set of parameters and the function body.
The basic syntax of the function is as follows:
<span style="font-size:18px;">function functionName(arg0, arg1, ... argN) { statements }</span>
There are three ways to declare functions specified by ECMAScript:
(1) Ordinary function declaration
<span style="font-size:18px;">function box(num1,num2){ return num1+num2; }</span>
(2) Use variable initialization or function declaration
<span style="font-size:18px;">var box=function(num1,num2){ return num1+num2; }</span>
(3) Use Function constructor to declare
function box(){ document.write("我是中国人!"); } box();//函数调用
The result of the operation is: I am Chinese!
(2) Function with parameters: Parameter variables are defined at the same time when the function is declared, and the parameters can be multiple.
function box(name,age) { document.write("你的姓名是:"+name+"你的年龄是:"+age); } box("张三","24");//函数调用
The result of the operation is: Your name is: Zhang San
Your age is: 24
(3) Function with return value
Functions with and without parameters have no defined return value, but are executed directly after being called. In fact, any function can realize the return value through the return statement followed by the value to be returned
1), function without parameters
function box(){ return "我是中国人!"; } document.write(box());
Same output as above: I am Chinese!
2), function with parameters
function box(name,age){ return "你的姓名是:"+name+"<br/>"+"你的年龄是:"+age; } document.write(box("张三","24"));//函数调用 document.write("<hr/>"); var demo=box("李四","23");//也可以重新赋值新的函数 document.write(demo);
The result of running is:
(4) As a function of value (more special)
First, let’s look at an example of a function as a regular variable:
function box(sum,num){ return sum+num;//这里传递的是函数的返回值和普通的变量一样 } function sum(num){ return num+10; } var result=box(sum(10),10); document.write("result="+result);
The output result of the page is: result=30
What is passed below is a function, carefully distinguish it from the above:
function box(sum,num){ return sum(num);//这里传递的是函数 } function sum(num){ return num+10; } var result=box(sum,10); document.write("result="+result);
The output result of the page is: result=20
3. Internal attributes of functions
? There are two special objects: arguments object and this object. The arguments object is an array-like object that contains all the parameters passed into the function. Its main purpose is to save the function parameters. The main attribute is length. This attribute is used to dynamically determine how many parameters the function has. But this object also has an attribute called callee, which is a pointer to the function that owns the arguments object.
(1)The length attribute of arguments object
JS function does not mind how many parameters are passed in, and will not cause errors due to inconsistent parameters. In fact, the function body can be accessed through the arguments object
Receive the parameters passed in.
Let’s first look at a problem we encounter when passing parameters in a function: when the function is declared, we don’t know how many parameters to define, but when we call the function, there are too many
problems or deficiencies.
function box(){ return arguments[0]+"|"+arguments[1]; } document.write(box(1,2,3,4,5,6));
输出的结果为:1|2。因此输出的显然与我们想要做的不符,那么怎么解决呢?
有了arguments对象的length属性我们就能可以得到参数的数量,避免上面的错误出现。
function box(){ return arguments.length; } document.write(box(1,2,3,4,5,6));
输出:6
我们还可以利用length属性来智能的判断有多少参数,然后把参数进行合理的应用,比如,实现一个加法运算,将所有传进来的数字累加,而数字的个数又不确定。
function box(){ var sum=0; if(arguments.length==0) { return sum; } for(var i=0;i<arguments.length;i++) { sum=sum+arguments[i]; } return sum;//返回累加结果 } document.write(box(1,2,3,4,5,6));
输出:21
(2)arguments对象的callee属性
还是来说问题:对于递归的问题我们很熟悉了,JS中也不例外
function box(num){ if(num<=1) { return 1; } else { return num*box(num-1);//递归 } } document.write(box(4));
输出:24
对于阶乘函数一般要用到递归算法,所以函数内部一定对调用自身,如果函数名不改变是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。为了解决这个问题,可以使用arguments.callee来代替。
function box(num){ if(num<=1) { return 1; } else { return num*arguments.callee(num-1)//递归 } } document.write(box(4));
输出:24
(3)this对象
函数内部另一个特殊的对象时this,其行为与Java和C#中的this大致相似,换句话说,this引用的是函数据以行操作的对象,或者说函数调用语句所处的那个作用域。当在全局作用域中调用函数时,this对象引用的就是window(window是一个对象,是JavaScript中最大的对象,是最外围的对象)。
var color="红色";//这里的color是全局变量,并且这个变量是window的属性 document.write(window.color+"<br/>"); document.write(this.color+"<br/>"); var box={ color:"蓝色",//这里的color是box下的属性,是局部变量 sayColor:function(){ return this.color;//此时的this只能是box中的color } }; document.write(box.sayColor()+"<br/>");//局部的 document.write(this.color);//全局的
运行的结果为:
四、函数属性和方法
(1)JavaScript中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype。其中,length属性表示函数希望接受的命名参数的个数。
function box(num1,num2){ return num1+num2; } document.write(box.length);
输出的结果;2
对于prototype属性,它是保存所有实例方法的真正所在,也就是原型。这个属性我们先不做过多的介绍。prototype属性下有两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
function box(num1,num2){ return num1+num2; } function sayBox(num1,num2){ return box.apply(this,[num1,num2]);//this表示作用域,这里是window,[]表示box所需的参数 } function sayBox2(num1,num2){ return box.apply(this,arguments);//arguments对象表示box所需的参数 } document.write(sayBox(10,10)+"<br/>"); document.write(sayBox2(10,10));
输出的结果为:20
20
(2)call()方法和apply()方法延伸
call()方法和apply()方法相同,它们的区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数作用域,没有变化,变化的只是其余参数都是直接传递给函数的。
function box(num1,num2){ return num1+num2; } function callBox(num1,num2){ return box.call(this,num1,num2);//区别apply()方法 } document.write(callBox(10,10));
输出的结果为:20
call()方法和apply()方法真正的作用是扩展函数赖以运行的作用域
var color="红色";//全局变量 var box={ color:"蓝色",//局部变量 }; function sayColor(){ return this.color; } document.write(sayColor()+"<br/>");//作用域在Window document.write(sayColor.call(this)+"<br/>");//作用域在Window下 document.write(sayColor.call(window)+"<br/>");//作用域在Window下 document.write(sayColor.call(box));//作用域在box下,对象冒充
输出的结果为:
使用call()方法或者apply()方法来扩充作用域的最大好处就是对象不需要与方法发生任何耦合关系。也就是说,box对象和sayColor()方法之间不会有多余的关联操作,比如;box.sayColor=sayColor;
五、ECMAScript闭包
ECMAScrip最易让人误解的一点是,它支持闭包。闭包,指的是词法表示包括不被计算的变量的函数,就是说,函数可以使用函数之外定义的变量。
其实我在前面的博文已经使用到了闭包,比如在轻松学习JavaScript七:JavaScript的流程控制语句中使用的变量time就是全局变量,函数myFunction()使用这个全局变量,并不是函数本身定义的。还是看一下那个实例吧:
var time=new Date().getHours(); document.write("当前北京时间:"+time); function myFunction() { var x=""; if (time<20) { x="Good day"; } document.getElementById("demo").innerHTML=x; }
(1)简单的闭包实例
在ECMAScript中使用全局变量是一个简单的闭包实例。请思考下面这段代码输出的结果是什么:
var sMessage = "hello world"; function sayHelloWorld() { document.write(sMessage); } sayHelloWorld();
在上面这段代码中,脚本被载入内存后,并没有为函数sayHelloWorld()计算变量sMessage的值。该数捕 sMessage的值只是为了以后的使用,也就是说,解释程序知道在调用该函数时要检查sMessage的值。sMessage将在函数调用sayHelloWorld()是在(最后一行)被赋值,显示消息"hello world"。
(2)复杂的闭包实例
在一个函数中定义另一个会使闭包变得更加复杂。例如:
var iBaseNum = 10;//全局变量 function addNum(iNum1, iNum2) { function doAdd() { return iNum1 + iNum2 + iBaseNum; } return doAdd(); } document.write(addNum(10,10));
这里,函数addNum()包括函数doAdd()(闭包)。内部函数是一个闭包,因为它将获取外部函数的参iNum1和iNum2以及全局变量iBaseNum的值。 addNum()的最后一步调用了doAdd(),把两个参数和全局变量相加,并返回它们的和。这里要掌握的重要概念是,doAdd()函数根本不接受参数,它使用的值是从执行环境中获取的,因此输出的结果为:30。
可以看到,闭包是 ECMAScript 中非常强大多用的一部分,可用于执行复杂的计算。就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。
以上就是本文的全部内容,希望对大家的学习有所帮助。