JavaScriptの機能を詳しく解説

小云云
リリース: 2018-03-17 15:53:18
オリジナル
1382 人が閲覧しました

(1).関数とは何ですか?

特定の関数を備えた n 個のステートメントのパッケージ。 関数のみ実行可能で、他の種類のデータは実行できません。関数もオブジェクトです。

(2)→コードの再利用→関数の定義を改善します

関数の使用法: 関数名 (パラメーター リストに対応する実際のパラメーター);

注: パラメーター リストはオプションであり、具体的な使用方法はニーズに応じて異なります。複数の定義された関数が同じ名前を持つ場合、後の関数が前の関数を上書きします。

(4). 関数がオブジェクトであることを証明する方法

1.fninstanceof Object=== true

2. 関数の属性とメソッドを使用します 属性:prototype/__proto__ メソッド: call()/apply()/bing()
3. 新しい属性/メソッドを追加できます

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

(5) この関数には 4 つの役割があります

一般関数 (直接呼び出し)、コンストラクター (呼び出し) new)、メソッド (オブジェクトによって呼び出される)、オブジェクト (内部プロパティ/メソッドの呼び出しによって呼び出される)


(6) 関数を呼び出す (実行する) 方法は?


①test():


を直接呼び出す② new test(): new

を介して呼び出す 注: new キーワードを使用すると、構築されたオブジェクトである関数をコンストラクターとして呼び出すことになります。コンストラクターの呼び出し時に返される値の場合、返されるオブジェクトはパーサー自体によって生成されます。 new キーワードを使用せずに関数を呼び出すことは、通常の関数呼び出しです。

③object.test(): オブジェクトを介した呼び出し

④test.call/apply(obj): 呼び出しを介した呼び出し

<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>
ログイン後にコピー
注: 関数における call() と apply() の役割:これらはすべて this のポイントを

に変更するために使用されます。 4 つの方法の違い: this の値が異なります

<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>
ログイン後にコピー
概要: 関数 (fn1()) を直接呼び出します。 : 出力はWindowですが、バインドバインディングオブジェクトがないことが前提となります。

bind は元の関数の this を変更しませんが、新しい関数を生成してこれをバインドするだけです

2.new 呼び出し: これは新しく作成されたオブジェクトです -----そして、返されるのは新しい

のインスタンス オブジェクト fn1{} 3. オブジェクトを介した呼び出し: メソッドを呼び出すのはオブジェクト (このオブジェクト) です --- 返されるのは、新しいインスタンス オブジェクト fn1 です。{}

4.test.call/apply(obj) を呼び出す: 指定されたオブジェクト ---- 返されるオブジェクトは obj です

注: 関数 fn を呼び出します。 test() の場合、fn 関数は実行されません。 call()/apply()で呼び出された場合のみfn関数が実行されます

(7)メソッドと関数の違い

<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>
ログイン後にコピー
変数と関数の宣言

1.関数宣言の促進

a. 変数宣言の改善: var を通じて定義 (宣言) された変数は定義ステートメントの前にアクセスされ、値がアンダーファイン化されます

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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート