zoukankan      html  css  js  c++  java
  • JavaScript学习二

    1.   课程介绍

    • 1.  假继承(没有实现原型链);(了解)
    • 2.  真继承(实现了原型链);(掌握)
    • 3.  函数的高级使用;(掌握)
    • 4.  复习jQuery、事件命名空间、继承;(了解)
    • 5.  自定义简单jQuery插件;(掌握)
    • 6. 自定义jQuery datagrid插件;(掌握)
    1. 继承

    2.1.  为什么要学习继承

    面试,理解其它框架

    百度一下 Extjs(写了很多组件的继承),类似于easyui

    1. 复习Java的继承

    3.1.  Java继承结构图

     

    3.2.  父类User

    public class User {

             protected String name;

             protected Integer age;

     

             public User(String name, Integer age) {

                      this.name = name;

                      this.age = age;

             }

    3.3.  子类Student

    public class Student extends User {

             private  String  no;

     

             Public  Student(String name, Integer age, String no) {

                      // 首行:把子类的name,age属性传递给父类      子类调用父类的构造方法

                      super(name, age);

                      this.no = no;

             }       

    1. 假继承(没有实现原型链)

    JavaScript没有为开发人员提供继承的方法,我们需要手动实现继承;

    没有Java的extends继承关键字

    4.1.  实现步骤

    1. 定义好父类和子类,都使用function来定义
    2. 子类构造函数中去"调用父类的构造函数".如果父类有构造参数需要传入
    3. 为父类添加自己的原型成员,用于测试效果
    4. 把父类中的原型对象拷贝到子类的原型对象中
    5. 为子类添加自己的原型成员,用于测试效果

    4.2.  步骤1-2

    4.2.1.   定义父类

    function User(name) {

           this.name = name;

           this.getAbc = function() {

                  return this.name;

           }

    }

     

    4.2.2.   定义子类

    function Student(name, no) {

           //this.name = name;没有子类与父类的关系

           //1.子类构造函数中去"调用父类的构造函数".如果父类有构造参数需要传入.

           // 子类调用父类的有参构造方法

           // this===student

           //User.call(this, name);

           User.apply(this, arguments);

           this.no = no;

    }

    4.3.  步骤3

    //      3.为父类添加自己的原型成员,子类应该是继承过来的

    User.prototype.getName = function() {

             return this.name;

    }

    User.prototype.age = 20;

    4.4.  步骤4

    //  4.把父类中原型对象的属性拷贝到子类的原型对象中.

    // 方案1:

    //     Student.prototype = User.prototype;//把子类的原型属性直接赋值父类

    // 前者是地址引用,这样修改Student的原型 会直接修改父类User原型,这样不推荐  

    // 后者是原型属性拷贝,子类相对独立,不会影响父类

    for ( var p in User.prototype) {

             console.debug("p=" + p);

             Student.prototype[p] = User.prototype[p];

    }

    4.5.  步骤5

    //      5.为子类添加自己的原型成员

    Student.prototype.getNo = function() {

             return this.no;

    }

    4.6.  步骤6:测试

    var user = new User("张二娃");

    var student = new Student("王九蛋", 12345);

    console.dir(user);

    console.debug("-----------------");

    console.dir(student);

    console.debug(student instanceof User);// false

     

    1. 真继承(实现了原型链)

    5.1.  其实JS中的继承就是使用的一个原型链

    如果一个对象的原型对象上面还有原型对象,那么这个对象就相当于继承了原型对象上面的原型对象的类.

    var student = new Student("xxx", 25, 200);

    例如: 如果一个对象student 的原型对象Student.prototype(等价于studnet.__proto__)上面还有原型对象User.prototype,那么这个对象student 就相当于继承了原型对象Student.prototype上面的原型对象User.prototype的类User.

     

    如日期对象    Date prototype ==》Object prototype

    5.2.  标准的原型链继承链

    Student prototype ==》User prototype ==》Object prototype

     

    5.3.  完整代码

    //定义父类

    function User(name) {

             this.name = name;

             this.getName = function() {

                      return this.name;

             }

    }

     

    //定义子类

    function Student(name, no) {

             //this.name = name;没有子类父类的关系

             //1.子类构造函数中去"调用父类的构造函数".如果父类有构造参数需要传入.

             // 子类调用父类的有参构造方法

             // this===student

             //User.call(this, name);

             User.apply(this, arguments);

             this.no = no;

    }

     

    //      2.为父类添加自己的原型成员,子类应该是继承过来的

    User.prototype.getName = function() {

             return this.name;

    }

    User.prototype.age = 20;

     

    //  3.把父类中原型对象的属性拷贝到子类的原型对象中.

    // 方案1:这是一个野方法,只能在个别浏览器下面运行(SB IE无法运行).   最简单实用,但是兼容性问题

    // Student.prototype.__proto__ = User.prototype;

    //方案2:Student prototype(原型名称是User) ==》User prototype ==》Object prototype

    //     Student.prototype = new User();

    //方案3:Student prototype ==》User prototype ==》Object prototype

    //     必须支持ECMAScript5规范

    //Object.create根据参数User.prototype来创建原型User.prototype

    Student.prototype = Object.create(User.prototype);

    //上一行代码替换Student的原型,并且把constructor构造函数替换了,所以我们需要替换回来.

    //constructor: User(name)替换成constructor: Student(name,no)

     

    //修改Student构造方法的名称

    Student.prototype.constructor = Student;

     

    //      4.为子类添加自己的原型成员

    Student.prototype.getNo = function() {

             return this.no;

    }

     

    var user = new User("张二娃");

    var student = new Student("王九蛋", 12345);

    console.dir(user);

    console.debug("-----------------");

    console.dir(student);

    console.debug(student instanceof User);// true

     

    1. 函数的高级使用

    6.1.  回调函数

    回调函数:回调函数就是一个通过函数指针调用的函数。如果你把函数的引用(地址)作为参数传递给另一个函数,当这个引用被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

    回调函数就是一个通过函数(对象)引用调用的函数;

    //添加了一个定时器,延迟1秒打印1

    setTimeout(function() {

             console.debug(1);

    }, 1000);

    //打印2

    console.debug(2);

     

    //     上面使用的是回调函数也是匿名函数

    //     下面就把匿名函数改为有名字的函数

     

    //该函数等time毫秒后执行一段代码.

    function fn(){

       alert("你行不行我分分钟终结你");

       alert("噹噹噹....");

    }

    setTimeout(fn,3000);

    6.2.  匿名函数:没有定义名称的函数

    一般这种函数作为值进行传递到某一个函数中或者是赋给其他变量。

    匿名函数作用:还可以包含一段代码,然后直接调用执行,避免产生全局变量。

    setTimeout(function(){

                      console.debug("aaaaaaaaaaaaaaa");

             },1000);

                     

             /*

             以下代码会导致全局变量中始终都存在x,y,而x和y计算后就不需要了,这种情况我们称为作用域污染.

                      var x = 10;

                      var y = 50;

                      var result = x*y;

                      console.debug(window);

             */

             /**

                      匿名函数写法:

                      (function(){

                       //推荐写法

                      })(); //自执行函数

     

                      ~function(){//可以在jQuery1.3版本上面看到

                              

                      }

                     

             **/

             //推荐写法

             (function(x,y){

                      window.result = x*y; //添加全局作用域中.

             })(10,50);

    如果不写匿名函数外面的(),出现语法错误。。。

     

    jQuery的源码就是这样写出来的

    6.3.  闭包

    闭包,指的是语法表示包括不被计算的变量的函数,

    也就是说,函数中可以使用函数之外定义的变量,封装特性

    6.3.1.   闭包第一种用法:函数中可以使用函数之外定义的变量。

             var msg = "呵呵";

             function sayMsg(){

                      //函数中可以使用函数之外定义的变量。

                      console.debug(msg);

             }

             sayMsg();

       

    6.3.2.         闭包第二种用法:通过闭包实现只读属性

    function User(name, age) {

             //以下代码都不能这样写了

             //              this.name = name;

             //              this.age = age;

             //实现一个功能:name,age是只读属性

             this.getName=function(){

                      return  name;

             };

             this.getAge=function(){

                      return  age;

             }

    }

     

    var user = new User("史珍香", 20);

    user.name = "xxx";//新增的一个属性,和传入的史珍香没有关系

    console.debug(user.getName());

    console.debug(user.getAge());

    console.debug(user.name); 

     

    1. 复习jQuery-选择器、事件监听

    <script type="text/javascript" src="jquery-2.1.1.min.js"></script>

    <script type="text/javascript">

             //jQuery的代码必须写在页面body加载完成之后

             $(function() {

                      //选择器

                      $("#xxx").html("yyy");

                      $(".mydiv").html("zzz");

     

                      //监听事件的方式:一般都使用前面2种方式

                      $("#xxx").click(function() {

                               console.debug(1);

                      });

                      $("#xxx").on('click', function() {//取消事件监听 off

                               console.debug(2);

                      });

                      $("#xxx").bind('click', function() {//取消事件监听 unbind

                               console.debug(3);

                      });

     

                      // 了解:如果监听的控件是某个小区域,先监听大的区域,添加一个过滤的条件(选择器)

                      $("body").on('click','.mydiv', function() {

                               console.debug(2);

                      });

             });

    </script>

    </head>

    <body>

             <div id="xxx" class="mydiv">xxx</div>

    </body>

    1. jQuery事件命名空间

    <script type="text/javascript" src="jquery-2.1.1.min.js"></script>

    <script type="text/javascript">

             //jQuery的代码必须写在页面body加载完成之后

             $(function() {

                      $("#xxx").on('click', function() {

                               console.debug(1);

                      });

                     

                      //只监听一次点击事件,然后取消监听

                      //click事件名称.manager命名空间

                      $("#xxx").on('click.manager', function() {//取消事件监听 off

                               console.debug(2);

                               $("#xxx").off('click.manager');

                      });

             });

    </script>

    </head>

    <body>

             <div id="xxx">xxx</div>

    </body>

    1. jQuery继承

    <script type="text/javascript" src="jquery-2.1.1.min.js"></script>

    <script type="text/javascript">

             //jQuery.extend([deep], target, object1, [objectN])

     

             //1.json的属性的抽取

             //使用场景:上传身份证照片:正面,背面

             var config = {

                      url : "upload.action",

                      xxx:"yyy"

             };

     

             //先传入目标对象的jspn,公共对象放在后面

             var config1 = jQuery.extend({

                      name : "pic1"

             }, config);

     

             var config2 = jQuery.extend({

                      name : "pic2"

             }, config);

     

             console.debug(config1);

             console.debug(config2);

            

            

             //2.jquery原型进行扩展.

             $.fn.extend({

                      myplugin1:function(){

                              

                      },

                      myplugin2:function(){

                              

                      }

             });

             //以上效果等同于

             //$.fn.myplugin1 = function(){};

             //$.fn.myplugin2 = function(){};

    </script>

    1. 简单jQuery插件

    <title>简单jQuery插件</title>

    <style type="text/css">

    .mydiv {

           background-color: red;

           100px;

           height: 100px;

    }

     

    .mydiv2 {

           background-color: yellow;

           200px;

           height: 200px;

    }

    </style>

    <script type="text/javascript" src="jquery-2.1.1.min.js"></script>

    <script type="text/javascript">

           $(function() {

     

                  $.fn.plugin = function(cls) {

                         $(this).hover(function() {

                                //添加样式

                                $(this).addClass(cls);

                         },function() {

                                //移除样式

                                $(this).removeClass(cls);

                         });

                  }

     

                  //插件的用法就是用jQuery的方法一样

                  $("#mydiv").plugin("mydiv2");

           });

    </script>

    </head>

    <body>

           <div id="mydiv" class="mydiv">000</div>

    </body>

    1. jQuery自定义插件datagrid

    显示表格数据的插件

    11.1.         效果

     

    11.2.         DatagridAction

    @Controller

    @Scope("prototype")

    public class DatagridAction extends BaseAction {

             @Autowired

             private IEmployeeService employeeService;

     

             // 显示一个页面,不添加数据

             // http://localhost/datagrid.action

             @Override

             public String execute() throws Exception {

                      return SUCCESS;

             }

     

             // 专门返回json数据

             // 应该是发出一个ajax请求 http://localhost/datagrid_json.action

             public String json() throws Exception {

                      // <param name="root">#map</param>

                      // 只拿前10条

                      putContext("map", employeeService.getAll().subList(0, 10));

                      // <result name="json" type="json">

                      return "json";

             }

    }

    11.3.         修改Employee

    必须重启tomcat

    @JSON(serialize = false)//roles属性json不输出

    public Set<Role> getRoles() {

             return roles;

    }

    11.4.         步骤1,属性id,username是写死的

    <script type="text/javascript" src="assets/js/jquery-2.0.3.min.js"></script>

    <script type="text/javascript">

             $(function() {

                      $.fn.datagrid = function(json) {

                               var url = json.url;

                               //创建插件的时候,已经传入url地址

                               if (url) {

                                        //获取table的jQuery对象,存起来

                                        var table = $(this);

                                        $.get(url, function(data) {

                                                 console.debug(data.length);//10

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

                                                          var tr = "<tr>";

                                                          tr+="<td>"+data[i].id+"</td>";

                                                          tr+="<td>"+data[i].username+"</td>";

                                                          tr+="</tr>";

                                                          table.append(tr);

                                                 }

                                        });

                               }

                      };

     

                      $("#dg").datagrid({

                               url : "datagrid_json.action"

                      });

             });

    </script>

    <title>问题点:属性id,username是写死的</title>

    </head>

    <body>

             <table id="dg" border="1">

                               <tr>

                                        <th>编号</th>

                                        <th>用户名</th>

                               </tr>

             </table>

    </body>

    11.5.         步骤2,年龄,头像,部门不能额外处理

     以下代码不能把大于25岁的年龄标红,头像不能显示(只有路径),部门名称显示不了

    <script type="text/javascript" src="assets/js/jquery-2.0.3.min.js"></script>

    <script type="text/javascript">

             $(function() {

                      $.fn.datagrid = function(json) {

                               var url = json.url;

                               //创建插件的时候,已经传入url地址

                               if (url) {

                                        //获取table的jQuery对象,存起来

                                        var table = $(this);

                                        //获取所有的th

                                        var ths = table.find("tr  th");

                                        console.debug(ths.length);//3

                                        $.get(url, function(data) {

                                                 console.debug(data.length);//10

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

                                                          var tr = "<tr>";

                                                          for (var j = 0; j < ths.length; j++) {

                                                             //获取th里面定义的属性field

                                                             var field = $(ths[j]).attr("field");

                                                             tr+="<td>"+data[i][field]+"</td>";

                                                          }

                                                          tr+="</tr>";

                                                          table.append(tr);

                                                 }

                                        });

                               }

                      };

     

                      $("#dg").datagrid({

                               url : "datagrid_json.action"

                      });

             });

    </script>

    <title>问题点:年龄,头像,部门额外处理不行</title>

    </head>

    <body>

             <table id="dg" border="1">

                               <tr>

                                        <th field="id">编号</th>

                                        <th field="username">用户名</th>

                                        <th field="password">密码</th>

                                        <th field="email">邮箱</th>

                                        <th field="age">年龄</th>

                                        <th field="headImage">头像</th>

                                        <th field="department">部门</th>

                               </tr>

             </table>

    </body>

    11.6.         步骤3,判断age,headImage,department都是写死的

    if("age"==field && data[i][field]>25){

    tr += "<td style='color:red'>" + data[i][field] + "</td>";

    }else if("headImage"==field){

    tr += "<td><img src='"+data[i][field]+"'></td>";

    }else if("department"==field){

             tr += "<td>" + data[i][field]["name"] + "</td>";

    }else{

             tr += "<td>" + data[i][field] + "</td>";

    }

    11.7.         步骤4,最终版本

    <script type="text/javascript" src="assets/js/jquery-2.0.3.min.js"></script>

    <script type="text/javascript">

             $(function() {

                      $.fn.datagrid = function(json) {

                               var url = json.url;

                               //创建插件的时候,已经传入url地址

                               if (url) {

                                        //获取table的jQuery对象,存起来

                                        var table = $(this);

                                        //获取所有的th

                                        var ths = table.find("tr  th");

                                        console.debug(ths.length);//3

                                        $.get(url, function(data) {

                                                 console.debug(data.length);//10

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

                                                          var tr = "<tr>";

                                                          for (var j = 0; j < ths.length; j++) {

                                                             //获取th里面定义的属性field

                                                             var field = $(ths[j]).attr("field");

                                                             //获取th里面定义的属性format

                                                             var format = $(ths[j]).attr("format");

                                                             if(format ){

                                                                      //调用window的函数,函数名是一个变量,当前的函数名有ageFarmat

                                                                      tr+="<td>"+window[format ](data[i][field])+"</td>";

                                                             }else{

                                                                      tr+="<td>"+data[i][field]+"</td>";                                                            

                                                             }

                                                          }

                                                          tr+="</tr>";

                                                          table.append(tr);

                                                 }

                                        });

                               }

                      };

     

                      $("#dg").datagrid({

                               url : "datagrid_json.action"

                      });

             });

             //必须写在最外面

             function ageFormat(value){

                      return value&&value>25?"<font color='red'>"+value+"</font>":value;

             }

            

             function imageFormat(value){

                      return value?"<img src='"+value+"'/>":"";

             }

             function deptFormat(value){

                      return value?value.name:"";

             }

    </script>

    <title>最终版</title>

    </head>

    <body> 

             <table id="dg" border="1">

                               <tr>

                                        <th field="id">编号</th>

                                        <th field="username">用户名</th>

                                        <th field="password">密码</th>

                                        <th field="email">邮箱</th>

                                        <th field="age" format ="ageFormat">年龄</th>

                                        <th field="headImage" format="imageFormat">头像</th>

                                        <th field="department" format="deptFormat">部门</th>

                               </tr>

             </table>

    </body>

    1. 课程总结

    12.1.         重点

    1. 真继承(实现原型链)
    2. jQuery选择器,事件监听,命名空间

    12.2.         难点

    1. 闭包
    2. jQuery自定义datagrid插件
    3. 常见异常
    4. 课后练习
    5. jQuery自定义插件datagrid
    6. 面试题
    7. JS继承的实现方式

     

    1、原型链继承

    2、构造继承

    3、实例继承

    4、拷贝继承

    5、组合继承

    6、寄生组合继承

    https://www.cnblogs.com/humin/p/4556820.html

     

    1. 继承实现方式:关键就是原型链

    Student.prototype.__proto__ = User.prototype;

    Student.prototype = Object.create(User.prototype);

    1. 面试题1

    <script type="text/javascript">

    var name = "The Window";

     

    var object = {

      name : "My Object",

     

      getNameFunc : function(){

    //      this==object

    console.debug(this);  

    var that = this;

        return function(){

    console.debug(this);  

    //      this==window

          return that.name;

        };

     

      }

     

    };

    console.debug(object.getNameFunc()());    

    </script>

     

    //1.调用了2次函数

    //2.第1步执行object.getNameFunc()返回是什么?匿名函数

    //         function(){

    //        return function(){

    //        return that.name;

    //       };

    //         }

    // 2.第2步执行执行第1步的函数:object.getNameFunc()()

           console.debug(object.getNameFunc()());    

    1. 面试题2

    <script type="text/javascript">

             var b = function() {

                      console.debug(123);

                      return function() {

                               console.debug(1234);

                      }

             }

    console.debug(b()());

             //1.函数要执行2次

    //     步骤1:调用b() --->打印123

    //     步骤2:调用b()() -->打印1234

    //     步骤3:拿到里面函数的返回值--> 打印undefined

    </script>

    16.1.         扩展知识

    1. 百度一下 javasript 继承
    2. 百度一下 ECMAScript5规范,最新版本简称es6规范,javascript的规范
  • 相关阅读:
    如何使用 SPICE client (virt-viewer) 来连接远程虚拟机桌面?
    小米手机会不会更好
    5年一梦
    每天进步一点点——分布式文件系统下的本地缓存
    iOS开发中的NSDateFormatter日期格式解析总结
    IOS假设将一个十六进制的color转换成UIColor,非常有用
    HH实习(hpu1287)(斐波那契运用)
    学习用CMake来编写Qt程序
    【MFC设置静态文本框背景为透明】
    排序(3)---------冒泡排序(C语言实现)
  • 原文地址:https://www.cnblogs.com/Src-z/p/11218827.html
Copyright © 2011-2022 走看看