ECMAScript 5 —— Function 类型 (四)
本篇文章聊聊函數屬性和方法 。
?
四. 函數屬性和方法
前面博文曾經提到過,ECMAScript 中的函數是對象,因此函數也有屬性和方法。每個函數都包含兩個屬性:length 和 prototype。其中,length 屬性表示函數希望接收的命名參數的個數,如下面的例子所示。
function sayName(name){alert(name); } function sum(num1, num2){return num1 + num2; } function sayHi(){ alert("hi"); } alert(sayName.length); //1 alert(sum.length); //2 alert(sayHi.length); //0以上代碼定義了 3 個函數,但每個函數接收的命名參數個數不同。首先,sayName()函數定義了一個參數,因此其 length 屬性的值為 1。類似地,sum()函數定義了兩個參數,結果其 length 屬性中保存的值為 2。而 sayHi()沒有命名參數,所以其 length 值為 0。
在 ECMAScript 核心所定義的全部屬性中,最耐人尋味的就要數 prototype 屬性了。對于ECMAScript 中的引用類型而言,prototype 是保存它們所有實例方法的真正所在。換句話說,諸如toString()和 valueOf()等方法實際上都保存在 prototype 名下,只不過是通過各自對象的實例訪問罷了。在創建自定義引用類型以及實現繼承時,prototype 屬性的作用是極為重要的(第 6 章將詳細介紹)。在 ECMAScript 5 中,prototype 屬性是不可枚舉的,因此使用 for-in 無法發現。
每個函數都包含兩個非繼承而來的方法:apply()和 call()。這兩個方法的用途都是在特定的作用域中調用函數,實際上等于設置函數體內 this 對象的值。首先,apply()方法接收兩個參數:一個是在其中運行函數的作用域,另一個是參數數組。其中,第二個參數可以是 Array 的實例,也可以是arguments 對象。例如:
在上面這個例子中,callSum1()在執行 sum()函數時傳入了 this 作為 this 值(因為是在全局作用域中調用的,所以傳入的就是 window 對象)和 arguments 對象。而 callSum2 同樣也調用了sum()函數,但它傳入的則是 this 和一個參數數組。這兩個函數都會正常執行并返回正確的結果。
call()方法與 apply()方法的作用相同,它們的區別僅在于接收參數的方式不同。對于 call()方法而言,第一個參數是 this 值沒有變化,變化的是其余參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來,如下面的例子所示。
function sum(num1, num2) {return num1 + num2; } function callSum(num1, num2) {return sum.call(this, num1, num2); } alert(callSum(10, 10)); //20在使用 call()方法的情況下,callSum()必須明確地傳入每一個參數。結果與使用 apply()沒有什么不同。至于是使用 apply()還是 call(),完全取決于你采取哪種給函數傳遞參數的方式最方便。如果你打算直接傳入 arguments 對象,或者包含函數中先接收到的也是一個數組,那么使用 apply()肯定更方便;否則,選擇 call()可能更合適。(在不給函數傳遞參數的情況下,使用哪個方法都無所謂。)
事實上,傳遞參數并非 apply()和 call()真正的用武之地;它們真正強大的地方是能夠擴充函數賴以運行的作用域。下面來看一個例子。
這個例子是在前面說明 this 對象的示例基礎上修改而成的。這一次,sayColor()也是作為全局函數定義的,而且當在全局作用域中調用它時,它確實會顯示"red"——因為對 this.color 的求值會轉換成對 window.color 的求值。而 sayColor.call(this)和 sayColor.call(window),則是兩種顯式地在全局作用域中調用函數的方式,結果當然都會顯示"red"。但是,當運行 sayColor.call(o)時,函數的執行環境就不一樣了,因為此時函數體內的 this 對象指向了 o,于是結果顯示的是"blue"。
使用 call()(或 apply())來擴充作用域的最大好處,就是對象不需要與方法有任何耦合關系。在前面例子的第一個版本中,我們是先將 sayColor()函數放到了對象 o 中,然后再通過 o 來調用它的;而在這里重寫的例子中,就不需要先前那個多余的步驟了。
ECMAScript 5 還定義了一個方法:bind()。這個方法會創建一個函數的實例,其 this 值會被綁定到傳給 bind()函數的值。例如:
在這里,sayColor()調用 bind()并傳入對象 o,創建了 objectSayColor()函數。object-SayColor()函數的 this 值等于 o,因此即使是在全局作用域中調用這個函數,也會看到"blue"。
每個函數繼承的 toLocaleString()和 toString()方法始終都返回函數的代碼。返回代碼的格式則因瀏覽器而異——有的返回的代碼與源代碼中的函數代碼一樣,而有的則返回函數代碼的內部表示,即由解析器刪除了注釋并對某些代碼作了改動后的代碼。由于存在這些差異,我們無法根據這兩個方法返回的結果來實現任何重要功能;不過,這些信息在調試代碼時倒是很有用。另外一個繼承的valueOf()方法同樣也只返回函數代碼。
?
?
好了,本篇文章就介紹到這兒,歡迎大家留言交流;喜歡或有幫助到您的話,點個贊或推薦支持一下!
轉載于:https://www.cnblogs.com/johnvwan/p/9552112.html
總結
以上是生活随笔為你收集整理的ECMAScript 5 —— Function 类型 (四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 炫酷告白网页
- 下一篇: Android应用中使用AsyncHtt