JavaScript上級プログラム設計学習ノート-関数式
9694 ワード
関数宣言については、関数宣言の昇格が重要な特徴であり、実行コード間で関数宣言が読み取られるという意味で、コード実行前に関数宣言を先に読み込むという意味です.これは関数宣言を呼び出し文に置くことができるということです.
後ろです
再帰する
argment.calleeは実行中の関数を指すポインタであることを知っていますので、関数への再帰的呼び出しは、例えば、
クローズドとは、別の関数のスコープにアクセスする権限がある変更の関数です.閉じたパケットを作成する一般的な方法は、関数の内部に別の関数を作成することです.
作用するドメインチェーンのこのような構成機構は,関数内の任意の変更を含む最後の値しか得られないという注意すべき副作用を引き出す.次の例のように:
私たちは、thisオブジェクトが動作時の関数に基づいて環境バインディングを実行していることを知っています.グローバル関数では、thisはwindowに等しく、関数があるオブジェクトとしての方法で呼び出されると、thisはそのオブジェクトに等しくなります.ただし、匿名関数の実行環境は大域的であるため、そのthisオブジェクトはwindowに向けられている.
前述のように、JavaScriptはブロックレベルのスコープの概念がない.これは、磁気カードがブロックステートメントで定義されている変数が、実際にはステートメントではなく関数に含まれていることを意味し、次の例を参照してください.
後ろです
sayHi();
function sayHi(){
alert("Hi!");
}
関数アップグレードの理解の鍵は、関数宣言と関数表現の違いを理解することです.//
if(condition){
function sayHi(){
alert("HI!");
}
}else{
function sayHi(){
alert("Yo!");
}
}
表面的には、上記のコードはconditionがtrueであるときに、sayHi()の定義を使用することを表しています.他の定義を使用します.実際、これはECMSScriptの中で無効な文法です.JavaScriptエンジンはエラーの修正を試みて、合理的な状態に転換します.ただし、関数式を使うなら大丈夫です.//
var sayHi;
if(condition){
sayHi=function(){
alert("Hi!");
}
}
else{
function sayHi(){
alert("Yo!");
}
}
この例は何の意外もないです.違う関数はconditionによってsayHiに割り当てられます.再帰する
argment.calleeは実行中の関数を指すポインタであることを知っていますので、関数への再帰的呼び出しは、例えば、
function factorial(num){
if(num<=1){
return 1;
}else{
return num*argument.callee(num-1);
}
}
包みを閉じるクローズドとは、別の関数のスコープにアクセスする権限がある変更の関数です.閉じたパケットを作成する一般的な方法は、関数の内部に別の関数を作成することです.
function createComparisonFunction(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object2[propertyName];
if(value1<value2){
return -1;
} else if(value1>value2){
return 1;
}else{
return 0;
}
}
}
クローズドと変更作用するドメインチェーンのこのような構成機構は,関数内の任意の変更を含む最後の値しか得られないという注意すべき副作用を引き出す.次の例のように:
function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]=function(){
return i;
}
}
return result;
}
この関数は関数配列を返します.表面から見ると、各関数は自分のインデックス値を返し、即位0の関数は0を返し、位置1の関数は1を返します.しかし、実際には、各関数は10を返します.各関数のスコープにはcreateFunctions関数の活動オブジェクトが保存されていますので、それらは最後のi.wに戻ります.しかし、別の匿名の函数を作成することによって強制的に閉じられた行為を予想通りにすることができます.function createFunctions(){
var result=new Array();
for(var i=0;i<10;i++){
result[i]= function(num){
return function(){
return num;
}
}(i)
}
return result;
}
thisオブジェクトについて私たちは、thisオブジェクトが動作時の関数に基づいて環境バインディングを実行していることを知っています.グローバル関数では、thisはwindowに等しく、関数があるオブジェクトとしての方法で呼び出されると、thisはそのオブジェクトに等しくなります.ただし、匿名関数の実行環境は大域的であるため、そのthisオブジェクトはwindowに向けられている.
var name="The Window";
var object={
name:"My Object",
getNameFunc:function(){
return function(){
return this.name;
}
}
}
alert(object.getNameFunc()()); //"The Window" (" ")
前に述べたように、各関数は呼び出し時に自動的に二つの特殊な変更を取得します.内部関数は、この2つの変数を検索すると、そのアクティブなオブジェクトだけが検索されますので、外部関数の2つに直接アクセスすることはできません.ただし、外部作用領域のthisオブジェクトを一つのクローズドパケットでアクセスできる変数に保存すると、クローズドがそのオブジェクトにアクセスできるようになります.以下の通りですvar name="The Window";
var object={
name:"My Object",
getNameFunc:function(){
var that=this;
return function(){
return this.name;
}
}
}
ブロックレベルのスコープを模倣する前述のように、JavaScriptはブロックレベルのスコープの概念がない.これは、磁気カードがブロックステートメントで定義されている変数が、実際にはステートメントではなく関数に含まれていることを意味し、次の例を参照してください.
function outputNumbers(count){
for(var i=0;i<count;i++){
alert(i);
}
alert(i); //
}
下記のように誤って同じ変数を再宣言しても、その値は変わりません.function outputNumbers(count){
for(var i=0;i<count;i++){
alert(i);
}
var i; //
alert(i); //
}
JavaScriptはこれまで何度も同じ変数を宣言したかを教えませんでした.このような状況になると、後の声明を無視するだけです.匿名関数は、ブロックレベルのスコープを模倣し、この問題を回避するために使用されてもよい.ブロックレベルのスコープとして使用される匿名関数のシンタックスは以下の通りである.(function(){
//
})();
上記のコードを定義し、直ちに匿名関数を呼び出しました.関数宣言をペアの括弧に含めます.これは実際に関数式です.続いているもう1つのペアの括弧は、すぐにこの関数を呼び出します.どこにいても、一時的に変数が必要であれば、プライベートスコープを使用することができます.function outputNumbers(count){
(function(){
for(var i=0;i<count;i++){
alert(i);
}
})();
alert(i); // !
}