国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

JavaScript學習筆記整理(6):函數

2018-06-19 12:00 更新
       函數就是一段可以反復調用的代碼塊。

函數使用function關鍵字來定義,還包括一個稱為形參(parameter)的標識符列表,這些參數在函數體內像局部變量一樣工作。

函數調用會為形參提供實參的值。函數使用它們實參的值來計算返回值,稱為該函數調用表達式的值。

除了實參之外,每次調用還會擁有另一個值---本次調用的上下文---這就是this關鍵字的值。

如果函數掛載在一個對象上,作為對象的一個屬性,就稱它為對象的方法。

JavaScript的函數可以嵌套在其他函數中定義,這樣它們就可以訪問它們被定義時所處的作用域中的任何變量,這就是JavaScript的閉包。 1、函數定義(聲明)

JavaScript有三種方法,可以定義一個函數。

(1)function命令

function name() {}

name是函數名稱標識符。函數名稱是函數聲明語句必需的部分。不過對于函數表達式來說,名稱是可選的:如果存在,該名字只存在于函數體內,并指向該函數對象本身。 圓括號:圓括號內可放置0個或多個用逗號隔開的標識符組成的列表,這些標識符就是函數的參數名稱。 花括號:可包含0條或多條JavaScript語句。這些語句構成了函數體。一旦調用函數,就會執(zhí)行這些語句。 (2)函數表達式

var f = function(x){   

  console.log(x);  

}

采用函數表達式聲明函數時,function命令后面不帶有函數名。如果加上函數名,該函數名只在函數體內部有效,在函數體外部無效。
(3)Function()
函數定義還可以通過Function()構造函數來定義

var f=new Function('x','y','return x+y');

等價于

var f=function(x,y){

  return x+y;

}

除了最后一個參數是函數體外,前面的其他參數都是函數的形參。如果函數不包含任何參數,只須給構造函數簡單的傳入一個字符串---函數體---即可。 不過,Function()構造函數在實際編程中很少會用到。

注意點:
如果同一個函數被多次定義(聲明),后面的定義(聲明)就會覆蓋前面的定義(聲明)

function f(){

 console.log(1);

}

f()  //1


function f(){

 console.log(2);

}

f()  //2

函數可以調用自身,這就是遞歸(recursion)

function f(x){

  if(x>2){

    console.log(x);

    return f(x-1);

  }else{

    return 1;

  }

}

f(4); 

// 4

//3

不能再條件語句中聲明函數 2、函數命名
任何合法的JavaScript標識符都可以用做一個函數的名稱。函數名稱通常是動詞或以動詞為前綴的詞組。 通常函數名的第一個字符為小寫。當函數名包含多個單詞時,可采取下劃線法,比如:like_this();也可以采取駝峰法,也就是除了第一個單詞之外的單詞首字母使用大寫字母,比如:likeThis();
3、被提前
就像變量的“被提前”一樣,函數聲明語句也會“被提前”到外部腳本或外部函數作用域的頂部,所以以這種方式聲明的函數,可以被在它定義之前出現的代碼所調用。

f()


function f(){}

上面的代碼不會報錯。
注意:以表達式定義的函數并沒有“被提前”。

f();  

var f = function (){};  

// TypeError: f is not a function

變量其實是分為聲明,賦值兩部分的,上面的代碼等同于下面的形式

var f;

f();

f = function() {};

調用f的時候,f只是被聲明了,還沒有被賦值,等于undefined,所以會報錯。

4、嵌套函數

在JavaScript中,函數可以嵌套在其他函數里。

function go(){   

  function play(){}   

  return play();  

}

5、函數調用

構成函數主體的JavaScript代碼在定義時并不會執(zhí)行,只有調用該函數,它們才會執(zhí)行。有4種方式調用JavaScript函數:
  • 作為函數
  • 作為方法
  • 作為構造函數
  • 通過它們的call()和apply()方法間接調用

5.1函數調用

f();

5.2方法調用

o.f=funciton(){} o.f();

5.3構造函數調用
如果函數或者方法調用之前帶有關鍵字new,它就構成構造函數調用。 凡是沒有形參的構造函數調用都可以省略圓括號。

var o=new Object(); var o=new Object;

5.4間接調用
6、函數的實參和形參
可選形參 當調用函數的時候傳入的實參比函數聲明時指定的形參個數要少,剩下的形參都將設置為undefined值。 為了保持好的適應性,一般應當給參數賦予一個合理的默認值。

function go(x,y){   

  x = x || 1;   

  y = y || 2;  

}

注意:當用這種可選實參來實現函數時,需要將可選實參放在實參列表的最后。那些調用你的函數的程序員是沒法省略第一個參數并傳入第二個實參的。
可變長的實參列表:實參對象

當調用函數時,傳入的實參個數超過函數定義時的形參個數時,是沒有辦法直接獲得未命名值的引用。

這時,標識符arguments出現了,其指向實參對象的引用,實參對象是一個類數組對象,可以通過數字下標來訪問傳入函數的實參值,而不用非要通過名字來得到實參。

function go(x){   

  console.log(arguments[0]);   

  console.log(arguments[1]);  

}  

go(1,2);  

//1

//2

arguments有一個length屬性,用以標識其所包含元素的個數。

function f(x){

  console.log(arguments.length);

}

f(1,2)  // 2

注意:arguments并不是真正的數組,它是一個實參對象。每個實參對象都包含以數字為索引的一組元素以及l(fā)ength屬性。

通過實參名字來修改實參值的話,通過arguments[]數組也可以獲取到更改后的值。

function f(x){   

  console.log(x);    // 1

  arguments[0]=null;   

  console.log(x);    // null

}


f(1);

在上面的例子中,arguments[0]和x指代同一個值,修改其中一個的值會影響到另一個。 注意:如果有同名的參數,則取最后出現的那個值。

function f(x,x){

 console.log(x);

}

f(1,2)  // 2

callee和caller屬性
arguments對象帶有一個callee屬性,返回它所對應的原函數。

7、將對象屬性用做實參

當一個函數包含超過三個形參時,要記住調用函數中實參的正確順序是件讓人頭疼的事。不過,我們可以通過名/值對的形式傳入參數,這樣就無法管參數的順序了。
function f(params){ console.log(params.name); } f({name:'a'}) 8、作為值的函數
在JavaScript中,我們可以將函數賦值給變量。 function f(){} var a=f;
9、函數作用域
作用域(scope)指的是變量存在的范圍。Javascript只有兩種作用域:一種是全局作用域,變量在整個程序中一直存在,所有地方都可以讀?。涣硪环N是函數作用域,變量只在函數內部存在。 在函數外部聲明的變量就是全局變量(global variable),它可以在函數內部讀取。

var a=1;

function f(){

 console.log(a)

}

f()  //1

上面的代碼中,函數f內部可以讀取全局變量a。

在函數內部定義的變量,外部無法讀取,稱為“局部變量”(local variable)。

function f(){

  var a=1;

}

v  //ReferenceError: v is not defined

上面代碼中,變量v在函數內部定義,所以是一個局部變量,函數之外就無法讀取。

函數內部定義的變量,會在該作用域內覆蓋同名全局變量。

var a=1;

function f(){

  var a=2;

  console.log(a);

}

f()  //2

a  //1

注意:對于var命令來說,局部變量只能在函數內部聲明,在其他區(qū)塊中聲明,一律都是全局變量。
函數的執(zhí)行依賴于變量作用域,這個作用域是在函數定義時決定的,而不是函數調用時決定的。
10、函數內部的變量提升
與全局作用域一樣,函數作用域內部也會產生“變量提升”現象。var命令聲明的變量,不管在什么位置,變量聲明都會被提升到函數體的頭部。

function f(x){

  if(x>10){

    var a = x -1;

  }

}


//等同于


function f(x){

  var a;

  if(x>10){

    a = x - 1;

  }

}

11、函數屬性、方法和構造函數
name屬性
name屬性返回緊跟在function關鍵字之后的那個函數名。

function f(){}

f.name   //f

length屬性
函數的length屬性是只讀屬性,代表函數形參的數量,也就是在函數定義時給出的形參個數。

function f(x,y){}

f.length  //2

prototype屬性 每一個函數都包含一個prototype屬性,這個屬性指向一個對象的引用,這個對象稱做“原型對象”(prototype object)。
call()方法和apply()方法

call()

語法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定義:調用一個對象的一個方法,以另一個對象替換當前對象。
說明: call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對象。

apply()

語法:apply([thisObj[,argArray]]) 定義:應用某一對象的一個方法,用另一個對象替換當前對象。
說明: 如果 argArray 不是一個有效的數組或者不是 arguments 對象,那么將導致一個 TypeError。 如果沒有提供 argArray 和 thisObj 任何一個參數,那么 Global 對象將被用作 thisObj, 并且無法被傳遞任何參數。 bind()方法
bind()方法是在ECMAScript 5中新增的方法。 toString()方法

函數的toString方法返回函數的源碼。

function f(){

  return 1;

}

f.toString()  

//function f(){

//  return 1;

//}

12、閉包
JavaScript的函數可以嵌套在其他函數中定義,這樣它們就可以訪問它們被定義時所處的作用域中的任何變量,這就是JavaScript的閉包。 閉包的最大用處有兩個,一個是可以讀取函數內部的變量,另一個就是讓這些變量始終保持在內存中,即閉包可以使得它誕生環(huán)境一直存在。

function f(a){   

  return function(){   

    return a++;   

  };   

}   

var c=f(1);   

console.log(c());    //1

console.log(c());   //2

console.log(c());  //3

閉包的另一個用處,是封裝對象的私有屬性和私有方法。

13、立即調用的函數表達式(
IIFE

在Javascript中,一對圓括號()是一種運算符,跟在函數名之后,表示調用該函數。

(function(){  

  statement

}())

上面的函數會立即調用。

注意:上面代碼的圓括號的用法,function之前的左圓括號是必需的,因為如果不寫這個左圓括號,JavaScript解釋器會試圖將關鍵字function解析為函數聲明語句。而使用圓括號,JavaScript解釋器才會正確地將其解析為函數定義表達式。

當然,下面的方法也會以表達式來處理函數定義的方法。

!function(){}();

~function(){}();

-function(){}();

+function(){}();


通常情況下,只對匿名函數使用這種“立即執(zhí)行的函數表達式”。它的目的有兩個:
一是不必為函數命名,避免了污染全局變量;
二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。
14、eval命令
eval命令的作用是,將字符串當作語句執(zhí)行。

eval('var a=1');

a  //1

eval沒有自己的作用域,都在當前作用域內執(zhí)行

JavaScript規(guī)定,如果使用嚴格模式,eval內部聲明的變量,不會影響到外部作用域。

(function(){

  'use strict';

  eval('var a=1');

  console.log(a);  //ReferenceError: a is not defined

})();



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號