一、面向对象相关基础特性
1、Arguments对象
Arguments对象可以看作是一个Array对象,它具有length属性,可以通过序号访问每一个参数。
function func(){ alert(arguments.length); alert(arguments[0]); }
Arguments有个callee属性,可以获取到执行的function对象的引用。可以使用它来实现匿名函数的内部递归调用。
var func = function(x){ if (x <= 1) return 1; return x * arguments.callee(x-1); }
2、函数的call方法和apply方法
两者都是将函数绑定到其它对象上执行。主要的区别在于:call方法在传递参数时是依次传入的;而apply方法是以array对象传入的。
obj1.func1.call(obj2, p1, p2);
obj1.func1.apply(obj2, [p1, p2]);
含义:将对象obj1的方法func1绑定到对象obj2上执行,并传入两个参数p1和p2。
3、for in语句的使用
var person = { name: "cjm", age: 30, sex: "male" }; var s = ""; for(key in person){ //循环属性名 s += key + "=" + person[key] + "; "; }
二、Parent类
//Parent类的构造函数 function Parent(x){ //私有变量 var version = 1; //有this开头的都是类的公共实例成员 //实例变量 this.x = x; //实例方法 this.say = function(){ alert("Parent.say"); } } //prototype属性在javascript中模拟了父类(超类)的角色 Parent.prototype.y = 15; //原型的实例变量。可以理解为:Parent类的父类的y实例变量值为15。可以被所有Parent实例对象继承,实例对象也可以覆盖它。 Parent.prototype.hello = function(){ //原型的实例方法。可以理解为:Parent类的父类的hello实例方法。可以被所有Parent实例对象继承,实例对象也可以覆盖它。 alert("Parent.prototype.hello"); } Parent.count = 1; //类变量。相当于Java的公共静态变量。 Parent.addCount = function(){ //类方法。相当于Java的公共静态方法。 Parent.count++; } var p = new Parent(10); //alert(p.x); //访问实例变量 //p.say(); //访问实例方法 //alert(p.y); //访问原型的实例变量 //p.hello(); //访问原型的实例方法 //p.y = 22; //覆盖原型的y属性值 //alert(Parent.count); //访问类变量 //Parent.addCount(); //访问类方法
通过prototype为对象增加实例变量和实例方法的另一种方式:
function Person(){} Person.prototype = { prop1: "prop1", func1: function(){ alert("invoke func1"); } }; var p = new Person(); //alert(p.prop1); //p.func1();
三、Children类
//Children类的构造函数 function Children(x, z){ this.z = z; Parent.call(this, x); //调用继承法。call函数:方法的调用,即this.Parent(1)。相当于Java的父类构造函数的调用。 //覆盖父类的say方法 var parentSay = this.say; //在覆盖之前,将父类的say方法存放在一个变量中,用于在子类中可以调用父类的被覆盖的方法。 this.say = function(){ alert("Chileren.say"); } this.testSay = function(){ parentSay.call(this); //调用父类被覆盖的方法 this.say(); } } Children.prototype = new Parent(); //原型继承法。可以理解为:Children类的父类是Parent类,即Children继承Parent Children.prototype.constructor = Children; //设置Children的构造函数为Children var c = new Children(1, 3); //alert(c.z); //访问实例变量 //alert(c.x); //访问父类的实例变量 //c.say(); //访问父类的实例方法 //alert(c.y); //访问父类的原型的实例变量 //c.hello(); //访问父类的原型的实例方法 //父类的静态成员不能被子类继承 //c.testSay(); //测试方法覆盖
四、私有静态变量:静态封装环境
Class1 = (function(){ //私有静态变量 var s_first = "private static field: s_first"; function constructor(){ //共有实例变量 this.first = "public field: first"; //共有实例方法 this.method1 = function(){ return "public methid: method1"; } //获取私有静态变量的值 this.method2 = function(){ return s_first; } //私有静态变量重新赋值 this.setFirst = function(_first){ s_first = _first; } } { return constructor; } })(); //匿名函数在创建后立即执行,或立即实例化为一个对象 //错误:私有静态变量不能被访问 //alert(Class1.s_first); var c1 = new Class1(); alert(c1.method2()); c1.setFirst("new value"); //改变私有静态变量的值 alert(c1.method2()); var c2 = new Class1(); alert(c2.method2()); //返回新值
new function(){ //私有静态变量 var s_first = "private static field: s_first"; Class1 = function(){ //获取私有静态变量的值 this.method2 = function(){ return s_first; } } }; var c1 = new Class1(); alert(c1.method2());
五、动态执行JS函数
<script language="javascript"> var Person = { name: "cjm", age: 30, sex: "male", setName: function(str){ this.name = str; }, handler: "myFunction" }; function myFunction(s1, s2){ alert(s1 + " _ " + s2); } </script> <script language="javascript"> if(Person.handler){ eval(Person.handler + ".call(new Object(), 's1', 's2');"); eval(Person.handler + ".apply(new Object(), ['s1','s2']);"); //传递参数的形式是用数组来传递 } </script>
六、静态类
Class1 = new function(){ var s_field = "private static field"; var s_method = function(){ return "private static method"; } this.field = "public static field"; this.method = function(){ return "public static method"; } } alert(Class1.method());
七、其它
var person = { name: "cjm", age: 30, sex: "male", setName: function(str){ this.name = str; } }; var s = ""; for(var key in person){ //循环属性名 s += key + "=" + person[key] + "; "; } //alert(s); //删除对象中的属性 delete person.name; //判断某个属性是否存在 //alert("name" in person);