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的规范
原文地址:https://www.cnblogs.com/Src-z/p/11218827.html