一、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织布 歌舞 琴棋书画