js类与对象

    技术2022-05-19  35

    <!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也是函数对象,递归思路

      

       //Objectprototype扩展 -- 所有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,他表示对函数本身的引用,这有利于实现无名函数的递归 或者保证函数的封装性,例如使用递归来计算1n的整数之和

           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)函数的applycall方法 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

           //可见 class1class2prototype是完全相同,是对同一个对象的引用,也就是共享的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

          

          

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

           Function.prototype.inherit = function(baseClass){ //Functionjs中可以充当类,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, 因此class1class2 没有共享prototype

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

              method: function(){

                 alert(2);

              }

           })

       

           //以下的继承有误:class1class2 是共享同一个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(){  //创建objonshow事件处理函数

             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" οnchange="show(this);">

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

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

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

      </select>

      </label>

    </form>

    </body>

    </html>


    最新回复(0)