>웹 프론트엔드 >JS 튜토리얼 >JavaScript 함수_javascript 기술에 대한 자세한 설명

JavaScript 함수_javascript 기술에 대한 자세한 설명

WBOY
WBOY원래의
2016-05-16 15:28:281365검색

함수는 언제 어디서나 실행할 수 있는 명령문의 집합입니다. 함수는 ECMAScript의 핵심으로서 매우 중요합니다. 함수는 호출될 때 실행되는 이벤트 기반 또는 재사용 가능한 코드 블록입니다. 즉, 함수는 한 번 정의되었지만 여러 번 호출하거나 실행할 수 있는 JavaScript 코드 조각입니다. 함수에는 매개변수가 있는 경우가 있는데, 이는 함수가 호출될 때 값이 할당되는 지역 변수입니다. 함수는 종종 이러한 매개변수를 사용하여 반환 값을 계산하며, 이는 함수 호출 표현식의 값이기도 합니다.
1. 함수 선언
함수는 모든 언어의 핵심 개념입니다. 함수를 통해 원하는 만큼의 명령문을 캡슐화할 수 있으며 언제 어디서나 호출하고 실행할 수 있습니다. JS의 함수는 function 키워드를 사용하여 선언되고 그 뒤에 매개변수 세트와 함수 본문이 옵니다.
함수의 기본 구문은 다음과 같습니다.

<span style="font-size:18px;">function functionName(arg0, arg1, ... argN) { 
 statements 
}</span> 

ECMAScript에서 지정한 함수를 선언하는 방법에는 세 가지가 있습니다.
(1) 일반 함수 선언

<span style="font-size:18px;">function box(num1,num2){ 
 return num1+num2; 
}</span>

(2) 변수 초기화 또는 함수 선언을 사용하세요

<span style="font-size:18px;">var box=function(num1,num2){ 
 return num1+num2; 
}</span> 

(3) 함수 생성자를 사용하여
선언

코드 복사 코드는 다음과 같습니다.
5d922835f04e91b1cf1e9cad217a2ea6 vax box= new Function('num1','num2','num1 num2');54bdf357c58b8a65c66d7c19c8e4d114

2. 함수 유형 및 함수 호출
ECMAScript 구문은
을 지정합니다. (1) 매개변수가 없는 함수: 함수 선언 시 매개변수가 없으며, 함수 호출 시 바로 사용할 수 있습니다.
function box(){ 
 document.write("我是中国人!"); 
} 
box();//函数调用 

작업 결과: 나는 중국인이다!
(2) 매개변수가 있는 함수: 매개변수 변수는 함수 선언과 동시에 정의되며, 매개변수는 여러 개가 될 수 있다.

function box(name,age) { 
 document.write("你的姓名是:"+name+"你的年龄是:"+age); 
} 
box("张三","24");//函数调用 

작업 결과: 귀하의 이름은: Zhang San
귀하의 나이: 24
(3) 반환값이 있는 함수
매개변수가 있는 함수와 없는 함수는 정의된 반환 값이 없지만 호출 후 바로 실행됩니다. 실제로 모든 함수는 반환할 값이 뒤따르는 return 문을 통해 반환 값을 구현할 수 있습니다
1) 매개변수가 없는 함수

function box(){ 
 return "我是中国人!"; 
} 
document.write(box()); 

위와 동일한 출력: 나는 중국인입니다!
2) 매개변수를 사용한 함수

function box(name,age){ 
 return "你的姓名是:"+name+"<br/>"+"你的年龄是:"+age; 
} 
document.write(box("张三","24"));//函数调用 
document.write("<hr/>"); 
var demo=box("李四","23");//也可以重新赋值新的函数 
document.write(demo); 

실행 결과는 다음과 같습니다.

(4) 가치의 함수로 (더 특별하게)
먼저 일반 변수인 함수의 예를 살펴보겠습니다.

function box(sum,num){ 
 return sum+num;//这里传递的是函数的返回值和普通的变量一样 
} 
function sum(num){ 
 return num+10; 
} 
var result=box(sum(10),10); 
document.write("result="+result); 

페이지의 출력 결과는 다음과 같습니다: result=30
아래에 전달되는 것은 함수입니다. 위의 것과 주의 깊게 구별하세요.

function box(sum,num){ 
 return sum(num);//这里传递的是函数 
} 
function sum(num){ 
 return num+10; 
} 
var result=box(sum,10); 
document.write("result="+result); 

페이지의 출력 결과는 다음과 같습니다: result=20
3. 함수의 내부 속성
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​? 두 가지 특별한 개체가 있습니다: 인수 개체와 이 개체. 인수 개체는 함수에 전달된 모든 매개 변수를 포함하는 배열과 유사한 개체입니다. 주요 목적은 함수 매개 변수를 저장하는 것입니다. 이 속성은 함수에 포함된 매개 변수 수를 동적으로 결정하는 데 사용됩니다. 하지만 이 객체에는 인수 객체를 소유한 함수에 대한 포인터인 callee라는 속성도 있습니다.
(1)인수 객체의 길이 속성
JS 함수는 전달되는 매개변수 수에 신경 쓰지 않으며, 일관성 없는 매개변수로 인해 오류가 발생하지 않습니다. 실제로 함수 본문은 인수 개체
를 통해 액세스할 수 있습니다. 전달된 매개변수를 받습니다.
​​​​ 먼저 함수에 매개변수를 전달할 때 직면하게 되는 문제를 살펴보겠습니다. 함수를 선언할 때 정의해야 할 매개변수가 몇 개인지 알 수 없지만, 함수를 호출할 때 매개변수가 너무 많습니다.
문제 또는 결함.

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 中非常强大多用的一部分,可用于执行复杂的计算。就像使用任何高级函数一样,使用闭包要小心,因为它们可能会变得非常复杂。

以上就是本文的全部内容,希望对大家的学习有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.