JS 类与对象

来源:互联网 发布:知乎最好的答案 编辑:程序博客网 时间:2024/06/04 23:35

转载文章的原地址为:http://blog.csdn.net/neo_liu0000/article/details/6333220

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

<title>js 类与对象</title>

</head>

 

<script type="text/javascript">

 

   /*

   //(1) 用定义函数的方式来定义类

   function class1(){

      alert("构造函数")

      //类成员的定义及构造函数

   }

   //这里的class1既是一个函数 也是一个类,可以将它理解成类的构造函数,负责初始化工作

  

  

   //(2) 使用new 操作符来获得一个类的实例

   var d = new Date();

   var obj1 = new class1();//会提示"构造函数"

   alert(typeof(obj1))

   //在js中,类与函数是一个概念

   //如果这个函数没有初始化类成员,则会返回一个空的对象

  

  

   //(3)使用[] 引用对戏的属性与方法

   //使用方法: 1 对象.属性(方法) 2 对象.["属性(方法)"]

   var arr = new Array();

   arr.push("abc");

   arr["push"]("def");

   alert(arr.length)

   //alert(arr["length"])

   //js对象就是一组属性(方法)的集合

   //这种用法适合 不确定具体要引用哪个属性(方法)的情况

   function User(){

       this.age = 22;

         this.name = "shi";

   }

  

   var user = new User();

  

   //动态显示不确定的属性值

   function show(slt){

      if(slt.selectedIndex != 0){

            alert(user[slt.value]);  //显示user对象中属性为slt.value的属性值 - 使用[]

               //alert(eval("user." + slt.value));// -- 使用eval()

         }

   }

  

   //使用[] 还可以使用 非标识符的字符串来作为属性名(如标识符中不允许以数字开头 或 有空格)

   user["my name"] = "robert";

   //alert( user["my name"])

  

  

   //(4)动态添加 修改 删除对象的属性与方法

   var man = new Object();

   //添加与修改属性

   man.name = "jack"

   //添加与修改方法

   man.sayHello = function(){

      alert("hello, my name is " + this.name)

   }

   man.sayHello();

  

   //删除属性

   man.name = undefined

   //删除方法

   man.sayHello = undefined

  

   //(5)使用{} 来创建无类型对象

   var woman = {

       name: "mary",

          sayHello: function(){

             alert("hello, my name is " + this.name)

          }

   }

  

   //(6) prototype 原型对象

   //每个函数都是一个对象,他们对应的类是“Function”,但是他们身份特殊,每个函数对象都具有一个子对象prototype

   //prototype 表示了该函数的原型,而函数也是类,则prototype 表示了一个类的成员的集合

   //空类

   function class2(){

   }

  

   class2.prototype.method1 = function(){

      alert("这是类的方法")

   }

  

   var obj3 = new class2();

   obj3.method2 = function(){

      alert("这是成员的方法")

   }

  

   obj3.method1();//调用类方法,只要是class2的对象都可以调用

   obj3.method2();//调用对象方法,仅仅是obj3调用

  

   //(7)认识函数对象 Function

   //内部对象: Function、 Date、 Array、 String -- 通过new Array()这样的语句返回一个对象,js内部有一套机制来初始化返回的对象,而不是由用户来指定对象的构造方式

   //用户自定义对象

   //js中,函数对象对应的类型是Function,可以使用new Function()来创建函数对象

   function myfun(a, b){

      return a + b;

   }

  

   //等价于

   var myfun1 = new Function("a", "b", "return a + b;")

  

   //对比数组对象

   var myarr = [];

   var myarr1 = new Array();

  

  

   //内部对象

   alert(typeof(Function));//function

   alert(typeof(new Function()));//function

  

   alert(typeof(Array));//function

   alert(typeof(new Array()));//object

 

   alert(typeof(Object));//function

   alert(typeof(new Object()));//object

  

   alert(typeof(Date));//function

   alert(typeof(new Date()));//object

  

   //(8)prototype

   //函数的prototype扩展 -- 所有函数对象的扩展

   Function.prototype.method3 = function(){

      alert("function 扩展")

   }

  

   function xfun(){

   }

  

   xfun.method3();

   xfun.method3.method3(); //其中 xfun.method3也是函数对象,递归思路

  

   //Object的prototype扩展 -- 所有js对象(包括函数对象)的扩展

    Object.prototype.getType = function(){

          alert(typeof(this))

       }

      

       var x = new Array();

       var y = function(){}

       x.getType();//Object

       y.getType();//function

      

       //(9)将函数作为参数传递

       function xx(){

         alert("xx")

       }

      

       function ff(xfun){

          xfun();

       };

      

       ff(xx)//将函数作为参数传递

      

       //(10)传递给函数的隐含参数 arguments

       function showargs(){

          for(var i=0; i < arguments.length; i++){

             alert(arguments[i])

          }

       }

      

       showargs(1,2,3,4,5)

  

    //arguments的另一个属性callee,他表示对函数本身的引用,这有利于实现无名函数的递归 或者保证函数的封装性,例如使用递归来计算1到n的整数之和

       var sum = function(n){

         if(1==n){

           return 1;

         }

         return n + sum(n -1);

       }

      

       alert(sum(100))

      

       var sum1 = function(n){

         if(1==n){

           return 1;

         }

         return n + arguments.callee(n -1);

       }

      

       alert(sum1(100))

      

       //(10)函数的apply、call方法 和 length属性

       //Function.prototype.apply(this对象, 参数数组)

       //Function.prototype.call(this对象, 参数1, 参数2, ...)   

       //作用是将函数绑定到另外一个对象上 运行

      

       function f1(){

         this.p = "f1";

         this.A = function(arg){

            alert(this.p + "|" +arg)

         }

       }

      

       function f2(){

         this.p = "f2";

         this.B = function(arg){

            alert(this.p + "|" +arg)

         }

       }

      

       var obj1 = new f1();

       var obj2 = new f2();

      

       obj1.A("by A") //f1 by A

       obj2.B("by B") //f2 by B

      

       obj1.A.apply(obj2, ["by A"]) //f2 by A

       obj2.B.apply(obj1, ["by B"]) //f1 by B

      

       obj1.A.call(obj2, "by A") //f2 by A

       obj2.B.call(obj1, "by B") //f1 by B

      

       //函数对象属性length  -- 函数定义的参数个数

       //arguments.length -- 实际传递的参数个数

       alert(f1.length)

      

      

       //(11)this 表示当前运行该函数的对象

       var obj = new Object();

       obj.p = "xxx";

       obj.getP = function(){

         alert(this.p); //this 指向的是 obj对象

       }

      

       //(12)类的实现机制

       //使用new 创建对象的过程

       //1 当解析器遇到new 操作符则创建一个空对象

       //2 开始运行class1这个函数,并将其中的this指针指向这个新建的对象

       //3 因为当给对象不存在的属性赋值时,解析器就会为对象创建该属性,这样函数的执行就是初始化这个对象的过程,即实现了构造函数的作用

       //4 当函数执行完后,new 操作符就会返回初始化后的对象

      

       //类成员

       function class1(){

          this.p = "b";

          this.method1 = function(){

            alert("class1方法:" + this.p)

          }

       }

      

       //使用prototype对象来定义类成员

       //当new 一个function时,该prototype对象的成员将自动赋予所创建的对象

       //new执行的过程

       //1 创建一个新对象,将this指针指向他

       //2 将函数的prototype对象的所有成员都赋给这个新建的对象

       //3  执行函数体,对这个对象进行初始化操作

       //4 返回创建的对象

      

       //类成员 -- 将成员保存在 class1.prototype原型对象中

       class1.prototype.showProp = function(){

          this.p = 'a'

          alert("prototype方法:" + this.p)

       }

      

       //注意:原型对象的定义必须在创建类实例的语句之前,否则他将不起作用

       var oo = new class1;

       oo.method1();

       oo.showProp();

      

       //js类的设计模式

       //定义一个类class1

       function class1(){

          //构造函数

       }

      

       //通过指定prototype对象来实现类的成员定义

       class1.prototype={

         prop1: "tt",

         method1: function(){}

       }

      

      

       //(13) 类的成员 + 静态成员

       function class1(){

          this.pp = "非静态成员";

       }

      

       class1.pp = "静态成员"

      

       //如果要为每一个函数对象添加通用的静态方法,可以通过函数对象的prototype来实现

       Function.prototype.showArgCount = function(){

          alert(this.length)//显示函数定义的参数个数

       }

      

       function tt(a){}

      

       tt.showArgCount()

      

       //示例 prototype-1.3.1.js

       //将函数作为一个对象的方法来运行

       Function.prototype.bind = function(object){

         var _method = this; //指的是实际运行的某个函数

         return funtion(){

           _method.apply(object, arguments); //将函数绑定到object上来运行

         }

       }

      

       //将函数作为事件监听器

       Function.prototype.bindAsEventListener = function(object){

         var _method = this; //指的是实际运行的某个函数

         return funtion(event){

           _method.apply(object, evnet || window.evnet); //将函数绑定到object上来运行, 使用evnet || window.evnet作为参数,将会在函数体中处理事件对象evnet || window.evnet

         }

       }

      

      

       //(14)使用 for(.. in ..)实现反射机制

       //反射机制 是指程序在运行时能够获得自身的信息,如一个对象在运行时知道自己有哪些属性与方法

       function showProp(obj){

              for(var p in obj){

                 alert(p + ":" + obj[p])

              }

       }

      

       var aa = { name: "aa", age: 13}

       showProp(aa)

      

       function setStyle(obj, _style){

         obj.style = _style;

       }

      

       function addStyle(obj, _style){

         for(var p in _style){

                 obj.style[p] = _style[p]

              }

       }

      

      

       //(15)利用共享prototype实现继承 -- 不能彻底的实现继承

       //定义class1

       function class1(){

       }

      

       //定义class1成员

       class1.prototype={

          m1: function(){

             alert(1);

          }

       }

      

       //定义class2

       function class2(){

       }

      

       //让class2继承class1 -- 共享prototype

       class2.prototype = class1.prototype

       //重载基类的方法

       class2.prototype.m1 = function(){

             alert(2);

       }

      

       //调用重载方法

       var obj1 = new class1();

       var obj2 = new class2();

       obj1.m1();//2

       obj2.m1();//2

       //可见 class1与class2的prototype是完全相同,是对同一个对象的引用,也就是共享的prototype

      

       //alert(typeof(obj1))//object

       //alert(typeof(obj2))//object

       alert(obj1 instanceof class1)//true

       alert(obj2 instanceof class1)//true

       alert(obj1 instanceof class2)//true

       alert(obj2 instanceof class2)//true

       //可见instanceof操作符的执行机制 -- 就是判断一个对象是否是一个prototype的实例

      

      

       //(16)利用反射机制与prototype来实现继承

       //定义class1

       function class1(){

       }

      

       //定义class1成员

       class1.prototype={

          m1: function(){

             alert(1);

          }

       }

      

       //定义class2

       function class2(){

       }

      

       //让class2继承class1 -- 复制prototype

       for(var p in class1.prototype){

              class2.prototype[p] = class1.prototype[p]

       }

       //重载基类的方法

       class2.prototype.m1 = function(){

             alert(2);

       }

      

       //调用重载方法

       var obj1 = new class1();

       var obj2 = new class2();

       obj1.m1();//1

       obj2.m1();//2

      

      

       //(17)js扩展 -- 继承的方法

       Function.prototype.inherit = function(baseClass){ //Function在js中可以充当类,this就是指类本身

          for(var p in baseClass.prototype){

               this.prototype[p] = baseClass.prototype[p];//复制基类的prototype

          }

       }

      

       //定义class1

       function class1(){

       }

      

       //定义class1成员

       class1.prototype={

          m1: function(){

             alert(1);

          }

       }

      

       //定义class2

       function class2(){

       }

      

       class2.inherit(class1)

       var obj2 = new class2();

       obj2.m1();//1

      

      

       //(18) prototype-1.3.1框架中雷继承实现机制

       //为Object添加静态方法: extend

       Object.extend = function(destination, source){

              for(var property in source){

               destination[property] = source[property];//复制对象属性

          }

          return destination;

       }

      

       //通过Object类为每个对象添加方法 extend

       Object.prototype.extend = function(obj){

          return Object.extend.apply(this, [this, obj]);

       }

      

       function class1(){}

      

       function class2(){}

      

       //让class2 继承于class1 并定义新成员

       //实际上是将class1的对象的属性复制到class2.prototype, 因此class1与class2 没有共享prototype

       class2.prototype = (new class1()).extend({

          method: function(){

             alert(2);

          }

       })

   

       //以下的继承有误:class1与class2 是共享同一个prototype

       //class2.prototype = class1.prototype.extend({

       //   method: function(){

       //      alert(2);

       //   }

       //}) 

      

       var obj = new class2()

       obj.method();

      

      

       //(19) 抽象类与虚函数

       //在面向对象语言中,抽象类的虚方法必须先被声明,但可以在其他方法中被调用

       //js 中,虚方法可以看做该类中没有定义的方法,但是已通过this指针使用了,同时,js中的虚函数不需经过声明,就可直接使用

       //为Object添加静态方法: extend

       Object.extend = function(destination, source){

              for(var property in source){

               destination[property] = source[property];//复制对象属性

          }

          return destination;

       }

      

       //通过Object类为每个对象添加方法 extend

       Object.prototype.extend = function(obj){

          return Object.extend.apply(this, [this, obj]);

       }

      

       //定义一个抽象的基类base,无构造函数

       function base(){}

      

       base.prototype = {

          initialize: function(){

             this.oninit(); // 调用一个虚方法

          }

       }

      

       //定义class1

       function class1(){

          //构造函数

       }

      

       //让class1继承base,并实现其中的oninit方法

       class1.prototype = (new base()).extend({

          oninit: function(){//实现抽象基类中的oninit虚方法

             alert("nothing")

          }

       })

      

       var obj = new class1();

       obj.initialize()

      

      

       //(20)使用抽象类的示例

       //prototype-1.3.1 定义了一个类的创建模型

       //Class是一个全局对象,有一个方法create,用于返回一个类

       var Class = {

          create: function(){

             return function(){  //返回一个类

                   this.initialize.apply(this, arguments) //initialize 虚方法在构造函数中被调用,在每次创建类实例都会被调用

                }

          }

       }

      

       //var class1 = Class.create();//获得一个新的类

      

       //类似于

       function class1(){

          this.initialize.apply(this, arguments)

         

          //this.initialize = function(){

          //   alert("hello")

          //}

       }

       //总结: initialize 是虚函数,必须要在prototype中实现

       class1.prototype.initialize = function(){

          alert("hello")

       }

      

       var obj = new class1();

      

      

       //(21) 最简单的事件模式 -- 将一个类的方法成员定义成事件

       function class1(){

         //构造函数

       }

      

       class1.prototype={

          show: function(){

            this.onshow(); //触发onshow事件

          },

          onshow: function(){} //定义事件接口

       }

      

       var obj = new class1();

       obj.onshow = function(){  //创建obj的onshow事件处理函数

         alert("onshow evnet")

       }

       obj.show();

      

      

       //(22)为事件处理函数传递参数

       //因为事件机制仅穿阿迪一个函数的名称,不带有任何参数的信息,所以无法传递参数进去

       //不考虑怎么将参数传进去,而是考虑如何构建一个无需参数的事件处理函数,该程序是根据由参数的事件处理程序来构建的,是一个外层的封装

       //将有参数的函数 封装为 无参数的函数

       function createFunction(obj, strFunc){

          var args = [];  //定义args 用于存储传递给事件处理函数的参数

          if(!obj){

             obj = window;  //如果没有obj参数,则认为是全局函数,则 obj = window;

          }

          //得到传递给事件处理函数的参数

          //-- 利用arguments对象处理第二个参数以后的隐式参数,即未定义形参的参数,并在调用事件处理程序时将这些参数传递进去

          for(var i = 2; i < arguments.length; i++){ // i 从2 开始,是因为要剔除显式声明的两个参数

             args.push(arguments[i]);

          }

          //用无参数函数来封装事件处理程序的调用

          return function(){

             obj[strFunc].apply(obj, args);//将参数传给指定的事件处理程序

          }

       }

      

       //调用的例子

       //一个事件处理程序是

       //sobj.eventHandler = function(arg1, arg2){

          //事件处理函数

       //}

      

       //调用形式为

       //createFunction(sobj, "eventHandler", arg1, arg2)

      

       //具体的调用过程

       function class1(){

         //构造函数

       }

      

       class1.prototype={

          show: function(){

            this.onshow(); //触发onshow事件

          },

          onshow: function(){} //定义事件接口

       }

      

       var obj = new class1();

      

       //创建事件处理函数

       function xxonshow(username){

          alert("hello," + username)

       }

      

       //绑定事件处理函数

       var username = "shijianhang"

       obj.onshow = createFunction(null, "xxonshow", username)

       username = "robert"

       //触发事件

       obj.show();

      

      

       //(23)自定义事件支持多绑定 -- 绑定多个事件处理函数

       function class1(){

         //构造函数

       }

      

       class1.prototype={

          show: function(){

             //触发onshow事件 -- 如果有时间绑定,则循环onshow数组

                if(this.onshow){

                  for(var i = 0; i < this.onshow.length; i ++){

                        this.onshow[i]();//调用事件处理函数

                     }

                }

          },

          //定义事件接口

          attachOnShow: function(_eHandler){

             if(!this.onshow){

                   this.onshow = [];//用数组来存储绑定的事件处理程序的引用

                }

                this.onshow.push(_eHandler)

          }

       }

      

       var obj = new class1();

      

       function onshow1(){  alert(1);  }

       function onshow2(){  alert(2);  }

       //绑定事件

       obj.attachOnShow(onshow1)

       obj.attachOnShow(onshow2)

       //触发事件

       obj.show();

       */

      

       //(24)使用cookie

       var Cookie = {

          setCookie: function(name, value, option){

             //用于存储赋值给 document.cookie 的 cookie格式字符串

                var str = name + "=" + escape(value);//设置值

                if(option){//设置选项

                   //如果设置了过期时间

                      if(option.expireDays){

                         var date = new Date();

                            var ms = option.expireDays * 24 * 3600 * 1000; //天数 -- 毫秒

                            date.setTime(date.getTime() + ms);

                            str += "; expires=" + date.toGMTString();

                      }

                      if(option.path) {

                           str += "; path=" + option.path; // 设置访问路径

                      }

                      if(option.domain) {

                           str += "; domain=" + option.domain; // 设置访问主机

                      }

                      if(option.secure) {

                           str += "; path=" + option.secure; // 设置安全性

                      }

                }

                document.cookie = str;

          },

          getCookie: function(name){

            var cookieArray = document.cookie.split("; ");//分隔成cookie的名值对

               var cookie = new Object();

               for(var i = 0; i < cookieArray.length; i++){

                  var arr = cookieArray[i].split("=");    //将名与值分开

                     if(arr[0] == name){

                        return unescape(arr[1]);            //如果是指定的cookie,则返回他的值

                     }

               }

               return "";

          },

          deleteCookie: function(name){

             this.setCookie(name, "", {expireDays:-1})

          }

       }

      

       Cookie.setCookie("user","shi");

       alert(Cookie.getCookie("user"));

      

       Cookie.deleteCookie("user")

       alert(Cookie.getCookie("user"));

      

</script>

 

<body>

<form id="form1" name="form1" method="post" action="">

  <label>

  <select name="select" onchange="show(this);">

    <option >请选择要查看的信息</option>

    <option value="age">年龄</option>

    <option value="name">姓名</option>

  </select>

  </label>

</form>

</body>

</html>

0 0