• MVC的JavaScript Web富应用开发——学习笔记(1)MVC和类


    MVC是一种设计模式 它将应用划分为三个部分: 数据,展现和用户交互

    一个事件的发生:
    1 用户和应用产生交互
    2 控制器的事件处理器被触发
    3 控制器从模型中请求数据,并交给视图
    4 视图数据呈现给用户
     
    模型:
    模型用来存放应用的所有数据对象
    模型不必知晓视图和控制器的细节,模型只需要包含数据以及直接和这些数据相关的逻辑,模型是最应该从应用中解耦出来的部分。
    当控制器从服务器抓取数据或创建新的纪录时,它就将数据包装成模型实例,也就是说数据是面向对象的,任何定义在这个数据模型上的函数或逻辑都可以被直接调用。
     
    视图:
    视图层是 呈现给用户的,用户与之产生交互。在JavaScript应用中,视图大多数是由HTML,CSS和JavaScript模板组成。除了简单的条件语句外,视图不应该包含任何其他逻辑。
    将逻辑混入视图之中是编程的大忌。
    这并不是说MVC不允许包含视觉呈现相关的逻辑,只要这部分逻辑没有定义在视图之内即可。
    我们将视觉呈现逻辑归类为“视图助手”:和视图有关的独立的小型工具函数。
     
     
    控制器:
    控制器是模型和视图之间的纽带。控制器从视图获得事件和输入,对它们进行处理,并相应的更新视图。当页面加载时,控制器会给视图添加事件监听,比如监听表单提交或按钮点击。然后当用户和应用产生交互时,控制器重的事件触发器就开始工作了。
     
    JavaScript中的类
    当使用new关键字来调用构造函数时,执行上下文从全局对象window变成一个空的上下文,这个上下文代表一个新生成的实例。
    默认情况下,如果你的构造函数中没有返回任何内容,就会返回this——当前的上下文。
     
    创建类
    创建自己的类模拟库
     1   var Class = function(){
     2     var klass = function(){
     3       klass.init.apply(this, arguments);   
     4     }
     5     klass.prototype.init() = function(){};
     6     return klass;
     7   };
     8   var Person = new Class;
     9 
    10   Person.prototype.init = function() {
    11     //基于Person的初始化内容
    12   }
    13 
    14   var person = new Person;
     
    给类的prototype起一个别名fn,写起来也方便。
    1   Person.fn = Person.prototype;
    2   Person.fn.run = function(){/*......*/};
     
    给类库添加方法
    我们采用另外一种方法添加属性
     1     klass.extend = function(obj){
     2       var extended = obj.extended;
     3       for( var i in obj){
     4         klass[i] = obj[i];
     5       }
     6       if( extended )
     7         extended(klass);
     8     };
     9 
    10     klass.include = function(obj){
    11       var included = obj.included;
    12       for( var i in obj){
    13         klass[i].fn = obj.[i];
    14       }
    15       if( included )
    16         included(klass);
    17     }
    18  
    19   var Person = new Class;
    20   Person.extend({
    21        find: function(id){/*...*/},
    22        exists: function(id){/*....*/}
    23   });
    24   var person = Person.find(1);
     
    同样,这里支持回调,即将属性传入后会触发这个回调:
    1   Person.extend({
    2      extended: funtcion(klass) {
    3           console.log(klass,"was extended");
    4      }
    5   });
     
    这种写法之美在于它可以支持模块。
    1   var ORMModule = {
    2      save: funtction() {
    3           //共享的函数
    4      }
    5   };
    6   Person.include(ORMModule);
    7   Asset.include(ORMModule);
     
    原型
    JavaScript是基于原型的编程语言,原型用来区别类和实例,原型是一个“模板”对象,它上面的属性被用做初始化一个新对象。任何对象都可以作为另一个对象的原型对象,以此来共享属性。可以理解为某种形式的继承。
    当你读取一个对象的属性时,JavaScript首先会在本地对象中查找属性,如果没有找到,会在对象的原型中查找,若还未找到则会继续查找原型的原型,知道找到Object.prototype。如果找到就返回值,否则返回undefined。
    换句话说,如果你给Array.prototype添加了属性,那么所有的JavaScript数组都有了这些属性。
     
    给类库添加继承
    现在来给我们定义的“类”库添加继承,
     1   var Class = function(parent){
     2     var klass = function(){
     3       klass.init.apply(this, arguments);   
     4     }
     5 
     6     if(parent){
     7       var subclass = function () {};
     8       subclass.prototype = parent.prototype;
     9       klass.prototype = new subclass;
    10     }
    11 
    12     klass.prototype.init() = function(){};
    13     klass.fn = klass.prototype;
    14     klass.fn.parent = klass;
    15     klass._super = klass.__proto__;
    16 
    17   /*
    18      extend.....
    19      include......
    20   */
    21 
    22     return klass;
    23   };
    将parent传入Class构造函数,所有的子类则会共享一个原型。
     
    函数调用
    JavaScript中,函数也是一个对象,然后不同的是,它是可以调用的,函数内上下文取决于调用它的位置。
    除了使用方括号调用函数外,还可以用apply和call调用。
    function.apply(this,[1,2,3]);
    function.call(this,1,2,3);
    function(1,2,3){}
    JavaScript中允许更换上下文是为了共享状态,尤其是在事件回调中。
    若要访问原始上下文,则可将原始上下文的this值存入一个局部变量中。
    使用call和apply还有一个功能,就是将调用委托给另一个调用
    即在获得参数args=jQuery.makeArray(arguments);和上下文this时, 可以调用其他部分功能相同的函数实现同样功能function.apply(this,args);
    其中arguments并不是真正的数组,需要通过jQuery的makeArray转换得到可以使用的数组。
     
    控制类库的作用域
     1   var Class = function(parent){
     2       var klass = function(){
     3         this.init.apply(this, arguments);
     4       };
     5       klass.prototype.init = function(){};
     6       klass.fn = klass.prototype;
     7       // 添加一个proxy 函数
     8       klass.proxy = function(func){
     9           var self = this;
    10           return(function(){
    11               return func.apply(self, arguments);
    12           });
    13       }
    14       // 在实例中也添加这个函数
    15       klass.fn.proxy = klass.proxy;
    16       return klass;
    17   };
     
    ECMAScript中加入了bind()函数用以控制调用的作用域
    有的浏览器不支持bind,所以我们也可以自己手动实现bind()
     1   if(!Function.prototype.bind){
     2     Function.prototype.bind = function(obj) {
     3       var slice = [].slice;
     4       args = slice.call(arguments,1),
     5       self = this,
     6       nop = function() {},
     7       bound = function() {
     8         return self.apply( this instanceof nop ? this:(obj || {}),
     9           args.concat(slice.call(arguments)));
    10       };
    11       nop.prototype = self.prototype;
    12       bound.prototype = new nop;
    13       return bound;
    14     };
    15   }
    推荐es5-shim
     
    添加私有函数
    很多开发者习惯在私有属性下面加_, 便于区分。但是方法太丑陋。。。
    我们可以利用JavaScript匿名函数来创建私有作用域。
    1   var Person = function(){};
    2   (function{
    3     var findById = function(){ /*....*/};
    4 
    5     Person.find = function(id) {
    6       if( typeof id = = "integer")
    7         return findById(id);
    8     };
    9   })();
     
    类库的方法:
    介绍了HJS和Spine。
  • 相关阅读:
    linux系统中如何查看日志 (转)
    php 获取随机字符串(原创)
    php Aes 128位算法
    linux 在线实验
    number随时间随机递增每天 不同 php(原创)
    php 判断字符串包含中文(转)
    同步,异步 阻塞,非阻塞, 异步+回调机制 线程队列 事件Event 丶协程
    线程的理论知识 开启线程的两种方式(Thread) 线程和进程之间的对比 线程的其他方法 守护进程 互斥锁 死锁现象,递归锁 信号量
    获取进程以及父进程的pid 验证进程之间的数据隔离 join方法 进程对象的其他属性 僵尸进程与孤儿进程(存在Linux系统中) 守护进程
    进程基础知识 操作系统 操作系统的发展史(多道技术) 进程介绍 python并发编程之:多进程
  • 原文地址:https://www.cnblogs.com/oneX/p/3662918.html
Copyright © 2020-2023  润新知