函數是 JavaScript 中的基本數據類型,在函數這個對象上定義了一些屬性和方法,下面我們逐一來介紹這些屬性和方法,這對於理解Javascript的繼承機制具有一定的幫助。
- 屬性(Properties)
- arguments
獲取當前正在執行的 Function 對象的所有參數,是一個類似數組但不是數組的對象,說它類似數組是因為其具有數組一樣的訪問性質及方式,可以由arguments[n]來訪問對應的單個參數的值,並擁有數組長度屬性length。還有就是arguments對象存儲的是實際傳遞給函數的參數,而不局限於函數聲明所定義的參數列表(length),而且不能顯式創建 arguments 對象。下面的Sample說明了這些性質。
function testArg(a, b) { var actCount = arguments.length, expCount = testArg.length, result; result = "Expected arguments' count is " + expCount + ";<br/>"; result += "Actual arguments' count is " + actCount + ".<br/>"; result += "They are:<br/>"; for (var i = 0; i < actCount; i++) { result += arguments[i] + ";<br/>"; } if (arguments instanceof Array) { result += "arguments is an Array instance." } else if (arguments instanceof Object) { result += "arguments is an Object instance." } document.write(result); } testArg(1); //output result is: Expected arguments' count is 2; Actual arguments' count is 1. They are: 1; arguments is an Object instance.
- length
獲取函數定義的參數個數,
functionName.length
不同於arguments.length,這點我們在上面有介紹。因為Javascript調用函數時候對函數參數不作任何個數和類型檢查,也就沒有函數調用錯誤概念。但是我們可以利用functionName.length和arguments.length的不同,在函數調用內部來檢測參數個數檢測。
function checkVarCount(a, b) { if (checkVarCount.length !== arguments.length) { alert("The count of the parameters you passed into the function doesn't match the function definition."); } alert("Successfully call the function"); } checkVarCount(1, 2); //Successfully call the function checkVarCount(1); //The count of the parameters you passed into the function doesn't match the function definition.
- caller
獲取調用當前函數的函數。caller屬性只有當函數正在執行時才被定義。
functionName.caller
如果函數是從 JavaScript 程序的頂層調用的,則caller包含null。如果在字符串上下文中使用 caller 屬性,則其結果和 functionName.toString 相同,也就是說,將顯示函數的反編譯文本。
function test() { if (test.caller == null) { document.write("test is called from the toppest level"); } else { document.write("test is called from the function:<br/>"); document.writeln(test.caller.toString()); } document.write("<br />"); } //call from the top level test(); //output: test is called from the toppest level function testOuter() { test(); } //call from the function testOuter testOuter(); //output: //test is called from the function: //function testOuter() { test(); }
- callee
返回正被執行的 Function 對象,即指定的 Function 對象的正文。
[functionName.]arguments.callee
callee 屬性是 arguments 對象的一個成員,該屬性僅當相關函數正在執行時才可用。通常這個屬性被用來遞歸調用匿名函數。
var fac = function(n){ if (n <= 0) return 1; else return n * arguments.callee(n - 1); }(4); document.write(fac);//24
- constructor
獲取創建某個對象的函數。constructor 屬性是每個具有原型的對象的原型成員。 這包括除 Global 和 Math 對象之外的所有內部 JavaScript 對象。 constructor 屬性就是用來構造對象實例的函數引用。
// A constructor function. function MyObj() { this.number = 1; } var x = new String("Hi"); if (x.constructor == String) document.write("Object is a String."); document.write ("<br />"); var y = new MyObj; if (y.constructor == MyObj) document.write("Object constructor is MyObj."); // Output: // Object is a String. // Object constructor is MyObj.
- prototype
獲取對象的原型。每一個構造函數都有一個prototype屬性,指向另一個對象。這個對象的所有屬性和方法,都會被構造函數的實例繼承。這意味着,我們可以把那些不變的屬性和方法,直接定義在prototype對象上。
function Man(name, age) { this.name = name; this.age = age; } Man.prototype.sex = "M"; Man.prototype.struggle = function () { alert("day day up!!!!"); } var li = new Man("Leo", 10); alert(li.sex);//M li.struggle();//day day up Man.prototype.isStrong = true; alert(li.isStrong);//true
這樣我們也可以向已定義好的對象(包括javascript提供的原生對象)中追加方法和屬性,
var aa = new Number(2); alert(typeof (aa.add)); //undefined Number.prototype.add = function (add1) { return this + add1; } alert(aa.add(1)); // 3
- 方法
- apply
調用函數,並用指定對象替換函數的this值,同時用指定數組替換函數的參數。
functionName.apply([thisObj[,argArray]])
如果argArray為無效值,則會拋出"Object expected"錯誤;如果thisObj和argArray都沒有提供,則會使用當前this作為thisObj
function callMe(arg1, arg2) { var s = ""; s += "this value: " + this; s += "<br />"; for (i in callMe.arguments) { s += "arguments: " + callMe.arguments[i]; s += "<br />"; } return s; } document.write("Original function: <br/>"); document.write(callMe(1, 2)); document.write("<br/>"); document.write("Function called with apply: <br/>"); document.write(callMe.apply(3, [4, 5])); document.write("<br/>"); document.write("Function called with apply with invalid array: <br/>"); try{ document.write(callMe.apply(3,2)); } catch (e) { document.write(e.message); } document.write("<br/><br/>"); document.write("Function called with apply without any argument: <br/>"); document.write(callMe.apply()); //Output result: //Original function: //this value: [object Window] // arguments: 1 // arguments: 2 //Function called with apply: //this value: 3 // arguments: 4 // arguments: 5 //Function called with apply with invalid array: //Function.prototype.apply: Arguments list has wrong type //Function called with apply without any argument: //this value: [object Window]
- call
調用一個對象的方法,用另一個對象替換當前對象。
call([thisObj[, arg1[, arg2[, [, argN]]]]])
它允許您將函數的 this 對象從初始上下文變為由 thisObj 指定的新對象。 如果沒有提供 thisObj 參數,則 global 對象被用作 thisObj。與apply方法唯一不同的地方是,apply的第二個參數類型必須是Array,而call方法是將所有的參數列舉出來,用逗號分隔。
function callMe(arg1, arg2){ var s = ""; s += "this value: " + this; s += "<br />"; for (i in callMe.arguments) { s += "arguments: " + callMe.arguments[i]; s += "<br />"; } return s; } document.write("Original function: <br/>"); document.write(callMe(1, 2)); document.write("<br/>"); document.write("Function called with call: <br/>"); document.write(callMe.call(3, 4, 5)); // Output: // Original function: // this value: [object Window] // arguments: 1 // arguments: 2 // Function called with call: // this value: 3 // arguments: 4 // arguments: 5
- bind
對於給定函數,創建具有與原始函數相同的主體的綁定函數。 在綁定功能中,this對象解析為傳入的對象。 該綁定函數具有指定的初始參數。
function.bind(thisArg[,arg1[,arg2[,argN]]])
其中function, thisArg為必選項。返回一個與 function 函數相同的新函數,只不過函數中的this對象和參數不同。
// Define the original function. var checkNumericRange = function (value) { if (typeof value !== 'number') return false; else return value >= this.minimum && value <= this.maximum; } // The range object will become the this value in the callback function. var range = { minimum: 10, maximum: 20 }; // Bind the checkNumericRange function. var boundCheckNumericRange = checkNumericRange.bind(range); // Use the new function to check whether 12 is in the numeric range. var result = boundCheckNumericRange (12); document.write(result); // Output: true
以下代碼演示如何使用 arg1[,arg2[,argN]]] 參數。 該綁定函數將 bind 方法中指定的參數用作第一個參數和第二個參數。 在調用該綁定函數時,指定的任何參數將用作第三個、第四個參數(依此類推)。
// Define the original function with four parameters. var displayArgs = function (val1, val2, val3, val4) { document.write(val1 + " " + val2 + " " + val3 + " " + val4); } var emptyObject = {}; // Create a new function that uses the 12 and "a" parameters // as the first and second parameters. var displayArgs2 = displayArgs.bind(emptyObject, 12, "a"); // Call the new function. The "b" and "c" parameters are used // as the third and fourth parameters. displayArgs2("b", "c"); // Output: 12 a b c
<input type="button" id="start" value="Start" /> <input type="button" id="stop" value="Stop" /> <script type="text/javascript"> function Car(owner) { this.owner = owner; this.start = function () { //start the car console.log(this); //output: Car {owner: "Mike", start: function, stop: function} check.html:14 console.log(this.owner + "'s car is starting."); //output: Mike's car is starting. }; this.stop = function () { console.log(this); //output: <input type="button" id="stop" value="Stop" /> console.log(this.owner + "'s car is starting."); //output: undefined's car is stopping. }; } var btnStart = document.getElementById("start"), btnStop = document.getElementById("stop"), someCar = new Car("Mike"); if (document.attachEvent) { btnStart.attachEvent("onClick", someCar.start.bind(someCar)); btnStop.attachEvent("onClick", someCar.stop); } else if (document.addEventListener) { btnStart.addEventListener("click", someCar.start.bind(someCar), false); btnStop.addEventListener("click", someCar.stop, false); } </script>
從上面Sample我們發現,當不使用bind方法的時候,事件里面的this指向的觸發click事件dom元素input,它當然沒有owner屬性;如果利用bind指定事件里面的this對象,就能達到我們想要的效果。
- toString
返回對象的字符串表示形式。
objectname.toString([radix])
objectname必需,指定需要獲取字符串表示形式的對象。radix可選,為將數字值轉換為字符串指定一個基數,此值僅用於數字。
toString 方法是一個所有內置的 JavaScript 對象的成員。 它的行為取決於對象的類型:
Object Behavior Array 將 Array 的元素轉換為字符串。 結果字符串被連接起來,用逗號分隔。 Boolean 如果布爾值為 true,則返回“true”。 否則返回“false”。 Date 返回日期的文本表示形式。 Error 返回一個包含相關錯誤信息的字符串。 Function 返回如下格式的字符串,其中 functionname 是一個函數的名稱,此函數的 toString 方法被調用: function functionname( ) { [native code] }
Number 返回數字的文字表示形式。 String 返回 String 對象的值。 Default 返回 "[object objectname]",其中 objectname 為對象類型的名稱。 - valueOf
返回對象的原生值。
object.valueOf( )
Javascript內部各個對象定義的valueOf不同:
Object Return value Array 返回數組實例。 Boolean 布爾值。 Date 從 UTC 1970 年 1 月 1 日午夜開始的存儲的時間值(以毫秒為單位)。 Function 函數本身。 Number 數字值。 Object 對象本身。 這是默認值。 String 字符串值。 Math 和 Error 對象都沒有 valueOf 方法。