一、caller---傳回函數調用者
1 //傳回函數調用者
2 //caller的應用場景 主要用于察看函數本身被哪個函數調用
3 function fn() {
4 //判斷某函數是否被調用
5 if (fn.caller) {
6 alert(fn.caller.toString());
7 } else {
8 alert("函數直接執行");
9 }
10 }
11 function handleCaller() {
12 fn();
13 }
14 // fn被其他函數調用
15 handleCaller();
16 //fn沒有被其它函數調用而是直接執行
17 fn();
二、callee---傳回正被執行的 Function 對象
1 // 傳回正被執行的 Function 對象,也就是所指定的 Function 對象的正文.
2 // callee是arguments 的一個屬性成員,它表示對函數對象本身的引用
3 // arguments.callee.length可以擷取實參參數
4
5
6 //callee用處1 用來判斷實際參數跟行參是否一緻
7 function calleeLengthDemo(arg1, arg2) {
8 // callee表示目前正在執行的函數對象,其實是函數的一個執行個體化
9 alert(arguments.callee.toString());
10 if (arguments.length == arguments.callee.length) {
11 window.alert("驗證形參和實參長度正确!");
12 return;
13 } else {
14 alert("實參長度:" + arguments.length);
15 alert("形參長度: " + arguments.callee.length);
16 }
17 }
18 //當函數被執行的時候,生成一個執行個體
19 calleeLengthDemo(1);
20
21
22 //callee用處2 調用自身 - 比如遞歸函數
23 // 優點:這樣就讓代碼更加簡練。又防止了全局變量的污染
24 //如下是一個遞歸算法 - 計算 1+2+3+4+...+n
25 var fn=(function(n){
26 if(n>0) return n+arguments.callee(n-1);
27 return 0;
28 })(10);
29 alert('采用callee方式:'+fn);
30
31
32 // 傳統方式的缺點:
33 // 1,破壞了,零重複法則,當一旦函數名稱更改,需要更改多處
34 // 2,fn是一個全局變量,fn内部一般使用局部bianliang,而這裡是一個全局變量,這是一個潛在的全局變量污染
35 var fn=function(n){
36 if(n>0) return n+fn(n-1);
37 return 0;
38 }
39 alert('采用傳統方式'+fn(10));
三、constructor
1 // 什麼是構造函數 - -專門用于建立對象或者累的函數 -- 因為js中原來沒有對象的概念,通過函數來間接實作面向對象
2 //我們将建立對象的時候那個函數稱之為構造函數
3 //我們可以通過constructor屬性擷取某個對象的構造函數
4 //constructor 屬性就是用來構造對象執行個體的函數引用 - 後面的知識點
5 //構造函數 建立的對象
6 function Student(name) {
7 this.name = name;
8 }
9 var zhangsan = new Student('張三');
10 if (zhangsan.constructor == Student)
11 document.write("zhangsan是根據構造函數Student創造(執行個體化)出來的"+"<br />");
12
13
14 //字元串對象
15 var str = new String("Hi");
16 if (str.constructor == String)
17 document.write("str是根據構造函數String創造(執行個體化)出來的");
18
19 // 輸出:
20 // 學生類的構造函數是Student函數
21 // str的構造函數是String
四、prototype屬性
1 // prototype屬性 -- 原型建立對象的底層原理 - 重點 __proto__
2 //擷取對象的原型。
3 //每一個構造函數都有一個prototype屬性,指向另一個對象。
4 //這個對象的所有屬性和方法,都會被構造函數的執行個體繼承。
5 //這意味着,我們可以把那些不變的屬性和方法,直接定義在prototype對象上。
6
7 // 目前隻需要掌握通俗了解方式:對象的建立其實包含兩個部分:構造函數部分,原型部分
8 // 當我們new一個對象的執行個體的時候,這個執行個體能夠同時擁有構造函數對象和原型對象的屬性和方法就是通過prototype屬性來實作的
9 // 具體實作方式,下次詳細講解
10
11
12 //古代的男人
13 function Man(name, age) {
14 this.name = name;
15 this.age = age;
16 }
17
18
19 //這裡其實是兩個對象 Man 和 Man.prototype
20 //這兩個對象通過prototype屬性實作關聯
21 //關聯後的結果,Man對象繼承Man.prototype,進而使得Man擁有Man.prototype的所有屬性和方法
22
23
24 Man.prototype.sex = "純爺們";
25 //方法:戰鬥
26 Man.prototype.struggle = function () {
27 alert("方天畫戟,赤兔,征戰沙場!!");
28 }
29
30 //執行個體化一個男人
31 var 呂布 = new Man("呂布", 20);
32 alert(呂布.sex);//純爺們
33 呂布.struggle();//方天畫戟,赤兔,征戰沙場!!
34
35
36 //古代女人
37 function Woman(name, age) {
38 this.name = name;
39 this.age = age;
40 }
41 Woman.prototype.sex = "小家碧玉";
42 Woman.prototype.zhibu = function () {
43 alert("織布 歌舞 琴棋書畫");
44 }
45 var 貂蟬 = new Woman("貂蟬", 16);
46 alert(貂蟬.sex);//小家碧玉
47 貂蟬.zhibu();//d織布 歌舞 琴棋書畫