>  기사  >  웹 프론트엔드  >  JavaScript의 기능에 대한 자세한 설명

JavaScript의 기능에 대한 자세한 설명

小云云
小云云원래의
2018-03-17 15:53:181330검색

(1).함수란 무엇인가요?

특정 기능을 가진 n개의 문으로 구성된 패키지입니다. 함수만 실행 가능하며, 다른 유형의 데이터는 실행 가능하지 않습니다. 함수도 객체입니다.

(2) 함수의 역할

→ 코드 재사용 개선

→ 읽기 쉽고 의사소통이 쉽습니다

(3) 함수의 정의

方式一:函数声明(推荐使用)  function     函数名(参数列表) 
{  //执行代码  }方式二:函数表达式(推荐使用)   var 变量名 = function(参数列表) {(推荐使用)    //执行代码   }
 var 变量名 = function 函数名(参数列表) 
 {  //执行代码    }方式三:构造器(了解)
 function     函数名(参数列表) 
 {  //执行代码  }

<span style="font-size: 14px;">function xiYiJi() {//函数声明<br/>	console.log("您好")<br/>}<br/>var fn = function(){//表达式<br/>	console.log("函数表达式")<br/>};<br/>var fn2 = function show(){//表达式<br/>	console.log(1);<br/>}<br/>var fn3 = new Function("console.log(4)");//构造器<br/>fn3();</span>
.

함수 사용법: 함수 이름(매개변수 목록에 해당하는 실제 매개변수)

참고: 매개변수 목록 또는 매개변수는 선택 사항이며 특정 용도는 필요에 따라 다릅니다. 정의된 여러 함수가 동일한 이름을 갖는 경우 나중에 함수가 이전 함수를 덮어씁니다.

(4). 함수가 객체임을 증명하는 방법

1.fn instanceof Object=== true

2. 함수의 속성과 메소드를 사용합니다. 속성: 프로토타입/__proto__
            메소드: call()/apply()/bing()
3. 새로운 속성/메서드

<span style="font-size: 14px;">function fn () {}<br/>        console.log(fn instanceof Object=== true)//true<br/>        //3.可以添加新的属性/方法<br/>            fn.a=3;<br/>            console.log(fn.a)</span>

(5)를 추가할 수 있습니다. 이 함수에는 4가지 역할이 있습니다

일반 함수(직접 호출), 생성자(호출) new를 통해), Method(객체에 의해 호출), 객체(내부 속성/메서드를 호출하여 호출)

(6) 함수를 호출(실행)하는 방법은 무엇입니까?

①test(): 직접 호출

② new test(): new

을 통해 호출 참고: new 키워드를 사용하는 것은 생성된 객체인 생성자로 함수를 호출하는 것입니다. 생성자를 호출할 때 반환된 값이 있으면 반환된 객체는 파서 자체에 의해 생성됩니다. new 키워드를 사용하지 않고 함수를 호출하는 것은 일반적인 함수 호출입니다.

3object.test(): 객체를 통한 호출

4test.call/apply(obj): 호출을 통한 호출

<span style="font-size: 14px;">        var obj1 = {x: "obj"};<br/>        //声明一个函数a1,控制台输出函数中的上下文(this)        <br/>        function a1() {<br/>            console.log(this);<br/>        }<br/>        //函数a1调用call方法,传入obj1对象做上下文<br/>        a1.call(obj1);//Object {x: "obj"}<br/><br/>        var obj2 = {x: "obj"};     <br/>        function a2() {<br/>            console.log(this);<br/>        }<br/>        a2.apply(obj2);//Object {x: "obj"}<br/></span>

참고: 함수에서 call() 및 apply()의 역할: 이들은 모두 this의 요점을

4가지 방법의 차이점: this의 값이 다릅니다

<span style="font-size: 14px;">        var obj = {x: "obj"};<br/>        function fn1(){<br/>            console.log(this);<br/>            this.getColor=function (){<br/>                console.log(this);<br/>                return this.color;<br/>            }<br/>        }<br/>        fn1();//直接调用   输出第一个this-----》Window<br/>        var p = new fn1();//通过new来调用  输出第一个this-----》fn1{}(也就是输出p)<br/>        p.getColor();//通过对象来调用  输出第二个this-----》fn1{}(也就是输出p)<br/>        fn1.call(obj);//通过call来调用  输出第一个this-----》Object<br/>        fn1.apply(obj);//通过apply来调用   输出第一个this-----》Object<br/></span>

요약:

1 함수(fn1())를 직접 호출합니다. : 출력은 Window 이지만, 바인딩 바인딩 객체가 없다는 전제가 있습니다.

bind는 원래 함수의 this를 변경하지 않고 새 함수만 생성하고 이

2.new 호출을 바인딩합니다. 이것은 새로 생성된 객체입니다. -----그러면 반환되는 것은 Instance입니다. 새로운

의 object fn13. 객체를 통한 호출: 메소드를 호출하는 객체(이 객체)입니다. 반환되는 것은 호출할 새 인스턴스 객체 fn1입니다.{}

4.test.call/apply(obj): 지정된 객체 ----obj 객체가 반환됩니다

참고: 사이에서 함수 fn을 호출합니다. test()를 실행하면 fn 함수가 실행되지 않습니다. call()/apply()를 사용하여 호출해야만 fn 함수가 실행됩니다

(7) 메소드와 함수의 차이점

<span style="font-size: 14px;">var arr = [1,2,3,4,5]<br/>var a =12;   // 变量:自由的<br/>arr.a= 5;     //属性:属于一个对象<br/>function show(){     //函数:自由的<br/>     alert(‘a’);<br/>}<br/>arr.fn = function(){   //方法:属于一个对象<br/>     alert(‘b’);<br/>}<br/>其实方法就是函数,只不过方法是有所属的对象。<br/><br/>我们所熟知的,将函数绑定到 click 事件<br/>语法:$(selector).click(function)<br/></span>

변수와 함수 선언


1. 함수 선언 승격

a. 변수 선언 개선: var를 통해 정의(선언)된 변수는 정의 문 이전에 액세스되며 값은 underfined

console.log(a);

var a= 3 ;

//분석: a=3으로 정의하면 a의 값에 접근할 수 있지만 a의 값은 과소정의됩니다. 이는 변수 선언의 개선입니다

//console.log(b );b= 6; 그러나 b는 허용되지 않습니다. var


을 통해 선언해야 합니다.

b.函数声明提升:通过function声明的函数,在之前就可以直接调用,值为函数定义(对象object)

fn();

 function fn () {  console.log('1')  }

通过function声明的函数,在之前就可以直接调用,这个说明函数定义已经创建了。。

js引擎如何变量声明提升,函数声明提升?

     是通过预处理。

浏览器中的两大引擎:浏览器之所以能够将我们写的html代码、css代码以及js代码转换成一个炫丽的网页界面,是因为两大引擎的作用。
 →渲染引擎:解析html和css代码,转换成炫丽的静态界面

 →渲染引擎:解析html和css代码,转换成炫丽的静态界面

 →js引擎:解析并运行js代码,实现动态的交互效果。

js预解析:
  js代码在解释执行之前,有一个“预备的过程”。这个预备的过程被称为“预解析”。
  预备的过程做什么事情呢?

  把用var关键字所声明的变量名(仅仅只是变量名) 和 用函数声明的方式定义的函数(函数整体)提升到【当前执行环境】的顶部。

<span style="font-size: 14px;">console.log(a);<br/>var a=122;<br/>//这个会被解析成:<br/>var a;console.log(a);a=122;<br/>//所以不会报错,打印出undefined<br/><br/><br/>//2.函数声明方式创建的函数<br/>test1("hello");<br/>function test1(x){console.log(x)}<br/>//这个会被解析成:<br/>function test1(x){console.log(x)}<br/>test1("hello");<br/>//所以不会报错,打印出hello<br/><br/>//3.函数表达式的方式 创建的函数<br/>test2("hello js!");<br/>var test2=function test1(j){console.log(j)}<br/>//这个会被解析成:<br/>var test2;<br/>test2("hello js!");<br/>test2=function test1(j){console.log(j)}<br/>//所以会报错。test2没有定义函数。如果是这这样<br/>var test2=function test1(j){console.log(j)}<br/>test2("hello js!");<br/>//则不会报错。打印出hello js!</span>

关于函数声明,它最重要的一个特征就是函数声明提升,意思是执行代码之前先读取函数声明。这意味着可以把函数声明放在调用它的语句之后。如下代码可以正确执行:

<span style="font-size: 14px;">sum(1,2); //3  <br/>function sum(x,y){  <br/>    alert(x+y);  <br/>}  </span>

2.函数的参数

→形参:在定义函数时,括号中的参数列表就是形参。
  如:function 函数名(形参1,形参2,...){
   //执行代码
  }
→实参:在调用函数时,所传入的对应的实际的数据,就是实参。
  如:函数名(数据1,数据2,...);

→函数体内的 arguments
 在定义函数时,使用形参时,形参可以不写(不推荐),可以使用arguments 这个“伪数组”来获取所传入的实参。
  arguments[索引];   索引从0开始


  如:function 函数名(形参1,形参2,...){
   //执行代码
  }
→实参:在调用函数时,所传入的对应的实际的数据,就是实参。
  如:函数名(数据1,数据2,...);

→函数体内的 arguments
 在定义函数时,使用形参时,形参可以不写(不推荐),可以使用arguments 这个“伪数组”来获取所传入的实参。
  arguments[索引];   索引从0开始

3.返回函数的函数---返回值

return作用:终止函数,并返回数据。
使用方式:函数里若没有显示的使用return时,函数执行完后,最终返回undefined;
      return;  //执行到该句代码时,函数会终止,并返回undefined。
      return   数据;//执行到该句代码时,函数会终止,并返回指定的数据。

使用方式:函数里若没有显示的使用return时,函数执行完后,最终返回undefined;
      return;  //执行到该句代码时,函数会终止,并返回undefined。
      return   数据;//执行到该句代码时,函数会终止,并返回指定的数据。

案例:简易的计算器

<span style="font-size: 14px;"><script type="text/javascript"><br/>    var box = function(){<br/>        var a=1;<br/>        return function(){<br/>            alert(++a)<br/>        }<br/>    }<br/>    var newFunc = box();//因为上面返回return是函数体   所以box是函数<br/>    newFunc();//2<br/></script>                                                                                                                       <br/> 如果想让返回的函数立即执行,亦可以使用box()()来执行这段代码。</span>

4. 作用域作用域,指的是变量使用的范围。
→全局作用域:函数之外的环境(全局执行环境)
    全局变量:在全局执行环境中用var关键字所声明的变量就是全局变量,全局变量在程序中的任何地方都可以使用。
→局部作用域:一个函数就是一个独立的执行环境(函数体内就是一个局部执行环境)
 局部变量:在函数中用var关键字所声明的变量 或 函数定义中的形参,仅仅只能够在本函数(本作用域中)中使用。
→注意:
     情况一: 当全局变量 和 局部变量命名一样时,在函数中使用该变量时,会优先使用函数本身中定义的局部变量。
     情况二:关于形参,其实就相当于在函数内用var关键字声明了变量。
  如:function test(a,b){
  //var a,b;    
  }

→ 再看变量声明提升:

<span style="font-size: 14px;">var scope = &#39;global&#39;;<br/>function f(){<br/>    console.log(scope);<br/>    var scope = &#39;local&#39;;<br/>    console.log(scope);<br/>}<br/>由于函数内声明提升,所以上面的代码实际上是这样的<br/><br/>var scope = &#39;global&#39;;<br/>function f(){<br/>    var scope;    //变量声明提升到函数顶部<br/>    console.log(scope);<br/>    scope = &#39;local&#39;;    //变量初始化依然保留在原来的位置<br/>    console.log(scope);<br/>}<br/>经过这样变形之后,答案就就非常明显了。由于scope在第一个console.log(scope)<br/>语句之前就已经定义了,但是并没有赋值,因此此时scope的指是undefined.<br/>第二个console.log(scope)语句之前,scope已经完成赋值为’local’,所以输出的结果是local。</span>

→ JavaScript中没有块级作用域
  就是在 选择语句 或 循环语句 中定义的变量不像是在函数体内一样定义的变量是局部变量,而是全局变量

5.匿名函数 和 自执行函数

①匿名函数(简称IIFE)

顾名思义就是没有名字的函数。

a.function(){}这样定义的函数在语法上是错误的(因为它没有函数名字)。

b.  (function(){....})
   !function(){....}

   -function(){....}

var a = function(){......}

若是加上一些运算符的话,该函数就不会产生错误,此时的函数被称为“匿名函数”。

注意:(function(){//这里是块级作用域  })

以上代码的这种方式就是模仿了块级作用域(通常成为私有作用域);定义并立即调用了一个匿名函数。经函数声明包含在一对圆括号中,表示它实际上是一个函数表达式。而紧随其后的另一对圆括号会立即调用这个函数。

②自我执行函数(其实就是执行匿名函数):即定义和调用合为一体
  (function(){ // (匿名函数)();第一圆括号放匿名函数,第二个圆括号执行
      alert(1);
    })();
匿名函数定义玩之后可以即刻执行。

→匿名函数的作用:

  避免全局变量污染以及命名冲突。

补充:

<span style="font-size: 14px;">//1.把匿名函数自我执行的返回值赋给变量:<br/>    var box =  (function (){           <br/>           console.log(&#39;Lee&#39;);<br/>           return 3;<br/>    })();         //打印”Lee”;<br/>    console.log(box);   //如果没有return 3的话,打印出来就是 undefined<br/>	<br/>	//2.自我执行匿名函数的传参<br/>    (function (age){<br/>         alert(age);<br/>    })(100);          //弹出100<br/></span>
<span style="font-size: 14px;">自执行函数的三种写法<br/>var result = function (){<br/>    alert(2);<br/>}();<br/>另一种语法也可得到同样结果:<br/>var result = (function () {<br/>    console.log(2);<br/>})();<br/>将函数返回值分配给变量:<br/>var result = (function () {<br/>    return 2;<br/>}());<br/></span>



三. 回调函数

回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。

→ 函数是一种实际的数据。

→ 在定义函数时,是可以在括号中定义形参的。

→ 在括号中的形参就相当于变量。而变量将来要介绍实际的数据,实参。

<span style="font-size: 14px;">/*函数是一种数据。所以可以当做实参来使用*/<br/>        	function fn(f){<br/>        		f();<br/>        	}<br/>        	var a = function(){<br/>        		alert("我是回调的函数");<br/>        	}<br/>        	fn(a);//fn是主函数,参数为a函数本身,所以a是回调函数<br/><br/><br/>            fn(function(){<br/>                alert("我是回调过来的");<br/>            })//在fn的函数里直接调用函数,这个被调用的函数也就是回调函数<br/></span>

b.将回调函数的参数作为与回调函数同等级的参数进行传递


总结明了同时满足这三个条件就是回调函数:

*你定义的函数

*你没有直接调养

*但最终它会执行(在特定条件和时刻)

(2).常用的回调函数

*DOM事件函数

*定时函数

*ajax函数

*生命周期回调函数(组件,对象)

<span style="font-size: 14px;">//DOM事件函数<br/>            document.getElementById(&#39;id&#39;).onclick=function(){<br/>                alert(&#39;点击事件。。&#39;)<br/>            }<br/>            //定时函数<br/>            setTimeout(function(){<br/>                console.log(&#39;到点了&#39;);<br/>            },10000)<br/></span>


(3).匿名函数

如果没有名称(函数表达式),就叫做匿名回调函数

作用:a.隐藏内部实现b.不污染外部命名空间

<span style="font-size: 14px;">(function(){<br/>                var a = 123;<br/>                function foo(){<br/>                    console.log(a)<br/>                }<br/>            })();</span>

四.函数中this

1.this是什么?

*一个关键字,一个内置的引用变量

*在函数中都可以直接使用this

*this代表当前函数的调用对象

*在定义函数时,this还没有确定,只有在执行时才动态绑定的

记住:跟函数定义没关系,跟函数的执行有大大的关系。总之就是:函数在哪里调用才决定了this到底引用的是啥

2.如何确定this的值?

①test():直接调用
②new test():通过new来调用
③object.test():通过对象来调用
④test.call/apply(obj):通过call来调用

1.直接调用函数(fn1()),输出的是Window,但是有一个前提,就没有bind绑定对象。

bind不会改变原有函数的this,只是产生了一个新的函数,并绑定的this

2.new调用,则返回的是new 的实例对象fn1{}

3.通过对象来调用,返回的是new 的实例对象fn1{}

4.test.call/apply(obj)来调用,返回的是obj对象

注意:

(1).执行函数时:有步骤
        a.执行函数定义(也就是执行这整块function Person(color){...}代码,把这个整块看成一句语句,就是函数定义):本质是创建函数对象
        b.执行/调用 函数Person('red');
(2).函数对象:函数首先是一个对象,所以可以通过“ . ”来确定它内部的属性以及方法。
        如我用" () "   a() ,此时a则是函数,如a.yy();这时a就称函数对象。可以通过“ . ”来判断是否是函数对象
(3)通过对象调用的时候,称方法:p.getColor();其他的时候称函数(p.setColor.call(obj,'black');)p.setColor获取是一个属性值,而这个属性值就是函数

<span style="font-size: 14px;">function Person(color){<br/>console.log(this);<br/>this.color=color;<br/>this.getColor=function (){<br/>    console.log(this);<br/>    return this.color;<br/>}<br/>this.setColor=function (color){<br/>    console.log(this);<br/>    return this.color;<br/>}<br/>}<br/>Person(&#39;red&#39;);//输出是第一个 console.log(this);-----Window<br/>// this.getColor方法内的console.log(this)是不执行的,但是getColor函数定义出来了<br/><br/>var p = new Person("yello");//输出是第一个 console.log(this);-----Person {}(就是p) <br/><br/>p.getColor();<br/>//输出是第二个 console.log(this);-----Person {color: "yello"}(就是p) <br/><br/>var obj={};<br/>p.setColor.call(obj,&#39;black&#39;);<br/>//输出是第三个 console.log(this); ---obj  通过函数对象的call方法来执行函数<br/><br/>var text=p.setColor;//把p.setColor的属性值(函数)赋值给text<br/>text();//直接调用 输出的都是 Window<br/><br/>function fun1(){<br/>function fun2(){<br/>    console.log(this);<br/>}<br/>fun2();//直接调用 输出的都是 Window<br/>}<br/>fun1();<br/><br/><br/>//注意:fn.bind()<br/>function fn(){<br/>console.log(this)<br/>}<br/>const obj2={}<br/>const fn2=fn.bind(obj2);<br/>//bind不会改变原有函数的this,只是产生了一个新的函数,并绑定的this<br/>fn();//直接调用 输出的都是 Window<br/>fn2();//输出的是 obj2</span>

五.递归

1.递归的官方概念:

  程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

2.递归的案例:
如一组有规律的年龄
  10 、12、14、16、18、20、22、24......
  求第n个人的年龄?

  图解分析:
  两个阶段:回推阶段(前进)、递推阶段(返回)
  一个条件:边界条件;第一个人的年龄为10


<span   style="max-width:90%">function getAge(n){<br/>        		if(n==1){ //边界条件<br/>        			return 10;<br/>        		}else {<br/>        			return getAge(n-1) + 2;<br/>        		}<br/>        	}<br/><br/>        	var age = getAge(5);<br/>        	alert(age);<br/></span>

相关推荐:

JavaScript函数绑定用法解析

实例讲解JavaScript函数绑定用法

详细介绍JavaScript函数的作用域与this指向

위 내용은 JavaScript의 기능에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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