zoukankan      html  css  js  c++  java
  • 读书笔记-JavaScript面向对象编程(三)

    第7章 浏览器环境

    7.1 在HTML页面中引入JavaScript代码

    7.2概述BOM与DOM(页面以外事物对象和当前页面对象)

    7.3 BOM

      7.3.1 window对象再探(所以JavaScript核心函数也都是window对象的方法)

      7.3.2 window.navigator(浏览器信息,如window.navigator.userAgent)

      7.3.3 Firebug的备忘功能

      7.3.4 window.location(当前页面的URL信息,如设置href属性可实现页面跳转)

      7.3.5 window.history(访问页面的历史记录信息,三个方法:forward、back、go)

      7.3.6 window.frames(当前页面中所有frame的集合)

      7.3.7 window.screen(浏览器以外的桌面信息)

      7.3.8 window.open()/close()(打开/关闭新窗口,现已被页面内自定义弹窗代替)

      7.3.9 window.moveTo()/resizeTo()(移动浏览器窗口位置/调整浏览器窗口大小,不建议使用)

      7.3.10 window.alert()/prompt()/confirm()(系统弹窗)

      7.3.11 window.setTimeout()/setInterval()(系统定时器,延时/循环)

    setTimeout("alert('boo')",2000);//首参数是一个可以被eval执行的字符串,但应尽量避免
    setTimeout(function(){alert('boo')},2000)//推荐:将相关函数调用封装在另一个函数中

      7.3.12 window.document(等同于DOM)

    7.4 DOM

      7.4.1 Core DOM与HTML DOM(XML与HTML)

      7.4.2 DOM节点的访问(nodeType、nodeName、nodeValue、documentElement(根节点)、childNodes(子节点集合)、parentNode(父节点)、attributes(节点的属性集合)、textContent(获取节点中的文本内容)、innerHTML)

      (getElementByTagName、getElementByName,getElementById、nextSibling、previousSibling、firstChild、lastChild)

      7.4.3 DOM节点的修改(属性赋值或innerHTML覆盖)

      7.4.4 新建节点(creatElement、creatTextNode并appendChild,或使用innerHTML、choneNode(true/false)、insertBefore)

      7.4.5 移除节点(removeChild,replaceChild,innerHTML设置为‘’)

      7.4.6 只适用于HTML的DOM对象(document.body等价于document.getElementByTagName('body')[0])

      (document.images/applets/links/anchors/forms,document.write,document.cookies/title/referrer/domain)

    7.5 事件

      7.5.1 内联HTML属性法

    <div onclick="alert('boo!')">click</div>

      7.5.2 元素属性法

    <div id="mybtn">click</div>
    //以下JS部分
    document.getElementById('mybtn').onclick=function(){alert('boo!')}

      7.5.3 DOM的事件监听器(DOM level 2)

    var btn=document.getElementById('mybtn');
    btn.addEventListener('click',function(){alert('boo!')})

      7.5.4 捕捉法与冒泡法(addEventListener的第三个参数为false只使用冒泡法,stopPropagation阻止冒泡 )

      7.5.5 阻断传播(removeEventListener移除事件,由匿名函数定义的监听器是不能被移除的)

      7.5.6 防止默认行为(preventDefault)

      7.5.7 跨浏览器事件监听器(IE中没有addEventListener用attachEvent,没有target用srcElement,没有stopPropagetion用cancelBubble为true,没有preventDefault用returnValue为false,没有removeEventListener用detachEvent)

      7.5.8 事件类型

    7.6 XMLHttpRequest对象

      7.6.1 发送请求

    var xhr=new XMLHttpRequest();
    xhr.onreadystatechange=myCallback;
    xhr.open('GET','somfile.txt',true);
    xhr.send('')

       7.6.2 处理响应(当readystate为4时响应返回,继续检测xhr.status服务器返回代码,并进行下一步处理)

      7.6.3 在早于7的IE版本中创建XMLHttpRequest对象 

    var xhr=new ActiveXObject('MSXML2.XMLHTTP.3.0');

      7.6.4 A代表异步

      7.6.5 X代表XML

      7.6.6 实例示范

    7.7 本章小结

    7.8 练习题

    第8章 编程模式与设计模式

    8.1 编程模式

      8.1.1 行为隔离(HTML、CSS与JS隔离,即内容、外观与行为隔离)

      8.1.2 命名空间(只定义一个全局变量,其他变量和方法定义为该变量的属性,很多库都实现的namespace方法如下)

    var MYAPP={}
    MYAPP.namespace=function(str){
      var parts=str.split('.'),curr=MYAPP;
      for(var i in parts){
        if(!curr[parts[i]]){curr[parts[i]]={}}
        curr=curr[parts[i]]
      }
    }
    MYAPP.namespace('dom.style');
    //等价于如下
    var MYAPP={
      dom:{
        style:{}
      }  
    }

      8.1.3 初始化分支(根据浏览器特性,一开始判断后再给特定功能函数赋值,当这些功能函数被调用,就用不需要再做探测了,兼容性初始化)

    var MYAPP={};
    MYAPP.event={
      addListener:null,
      removeListener:null
    }
    if(typeof window.addEventListener==='function'){
      MYAPP.event.addListener=function(el,type,fn){el.addEventListener(type,fn,false);}
      MYAPP.event.removeListener=function(el,type,fn){el.removeEventListener(type,fn,false);}
    }else if(typeof document.attachEvent==='function'){//IE
      MYAPP.event.addListener=function(el,type,fn){el.attachEvent('on'+type,fn);}
      MYAPP.event.removeListener=function(el,type,fn){el.detachEvent('on'+type,fn);}
    }else{//older browsers
      MYAPP.event.addListener=function(el,type,fn){el['on'+type]=fn;}
      MYAPP.event.removeListener=function(el,type,fn){el['on'+type]=null;}
    }

      8.1.4 延迟定义(同初始化分支。第一次调用时被定义)

    var MYAPP={};
    MYAPP.myevent={
      addListener:function(el,type,fn){
        if(typeof window.addEventListener==='function'){
          MYAPP.myevent.addListener=function(el,type,fn){el.addEventListener(type,fn,false);}
        }else if(typeof document.attachEvent==='function'){//IE
          MYAPP.myevent.addListener=function(el,type,fn){el.attachEvent('on'+type,fn);}
        }else{//older browsers
          MYAPP.myevent.addListener=function(el,type,fn){el['on'+type]=fn;}
        }
        MAAPP.myevent.addListener(el,type,fn);
      }
    }

      8.1.5 配置对象(用于有很多参数的函数,用对象替代参数可以不考虑参数顺序,跳过默认值,扩展性更强,可读性更好)

      8.1.6 私有属性和方法(对象方法内部定义的局部变量和函数)

      8.1.7 特权函数(建立公共函数,它们可以访问内部私有属性和方法,如get/set方法)

      8.1.8 私有函数的公有化

    var MYAPP={};
    MYAPP.dom=(function(){
      var _setStyle=function(el,prop,value){console.log('setstyle')}
      var _getStyle=function(el,prop){console.log('getstyle')}
      return {
        setstyle:_setStyle,
        getstyle:_getStyle,
        yetAnother:_setStyle
      }
    })()
    MYAPP.dom.setstyle=function(){alert('b')}//外部可以改写setstyle方法,yetAnother依然指向_setStyle

      8.1.9 自执行函数(保证命名空间,特别适合执行一次性初始化任务)

      8.1.10 链式调用(前一个方法的结果(即返回对象)来调用下一个方法)

      8.1.11 JSON

    8.2 设计模式

      8.2.1 单件模式1

    var single={};//最基本的单件模式

      8.2.2 单件模式2(仅生成一个对象)

    function Logger(){
      if(typeof global_log==='undefined'){global_log=this;}
      return global_log;
    }
    var a=new Logger();
    var b=new Logger();
    alert(a===b);//true,此方法产生全局变量global_log
    var Logger=(function(){
      var instance=null;
      return {
        getinstance:function(){
          if(instance==null){instance=this};
          return instance;
        }
      }
    })()
    var a=Logger.getinstance();
    var b=Logger.getinstance();
    alert(a===b);//true,利用只执行函数和闭包来实现

       8.2.3 工厂模式(创建对象模式)

    //假如我有三个不同的构造器,它们功能相似,但处理细节不同
    var MYAPP={};
    MYAPP.dom={};
    MYAPP.dom.Text=function(){
      this.insert=function(where){
        var txt=document.createTextNode(this.url);
        where.appendChild(txt)
      }
    };
    MYAPP.dom.Link=function(){
      this.insert=function(where){
        var link=document.createElement('a');
        link.href=this.url;
        link.appendChild(document.createTextNode(this.url));
        where.appendChild(link)
      }
    };
    MYAPP.dom.Image=function(){
      this.insert=function(where){
        var img=document.createElement('img');
        img.src=this.url;
        where.appendChild(img)
      }
    };
    //使用三个构造器的方法都一样,设置URL属性并调用insert方法
    var t=new MYAPP.dom.Text();
    t.url='http://www.baidu.com/1.jpg';
    t.insert(document.body)
    //如果我们暂时不知道创建哪种对象,需要根据用户触发按钮来决定,按钮提供type表示创建类型,如下
    var o;
    if(type ==='Text'){o=new MYAPP.dom.Text();
    }else if(type ==='Link'){o=new MYAPP.dom.Link();
    }else if(type ==='Image'){o=new MYAPP.dom.Image();}
    o.url='http://...';
    o.insert();
    //添加工厂方法factory,避免如上判断
    MYAPP.dom.factory=function(type){return new MYAPP.dom[type];}
    var o=MYAPP.dom.factory(type);
    o.url='http://...';
    o.insert();

      8.2.4 装饰者模式(结构性模式,主要拓展对象的功能)

    //装饰者模式实例:装饰一颗圣诞树
    var tree={
      decorate:function(){console.log('确保树不会倒');}
    };
    //接着定义方法用于添加额外的装饰器,装饰器实现为构造器函数,都继承tree
    tree.getDecorate=function(deco){tree[deco].prototype=this;return new tree[deco];}//让每一个装饰后对象的原型等于父级
    //下面创建装饰器,将他们设置为tree的属性(保证命名空间),它们提供decorate方法,单先调用父类的decorate
    tree.RedBalls=function(){
      this.decorate=function(){this.RedBalls.prototype.decorate();console.log('上面放一些红球')}
    }
    tree.BlueBalls=function(){
      this.decorate=function(){this.BlueBalls.prototype.decorate();console.log('下面放一些蓝球')}
    }
    tree.Angel=function(){
      this.decorate=function(){this.Angel.prototype.decorate();console.log('在树顶放一个小天使')}
    }
    //再把所有的装饰器都添加到基础对象上
    tree=tree.getDecorate('BlueBalls')
    tree=tree.getDecorate('Angel')
    tree=tree.getDecorate('RedBalls')
    tree.decorate();
    //tree.Redballs的原型为父类tree.Angel的原型为父类tree.RedBalls的原型为父类tree(初始状态)
    console.log(tree.getDecorate('BlueBalls').getDecorate('Angel').getDecorate('RedBalls'))

      8.2.5 观察者模式(行为模式,主要用于处理不同对象间的交互通信)

    //先创建一个观察者,它包含由回调函数构成的订阅者数组,用于增加和删除订阅者的方法,publish授受并传递数据给订阅者,make将任意对象转变为发行商并添加上述方法
    var observer={
      addSubscriber:function(callback){this.subscribers[this.subscribers.length]=callback;},
      removeSubscriber:function(callback){
        for(var i=0; i<this.subscribers.length;i++){if(this.subscribers[i]==callback){delete(this.subscribers[i])}}
      },
      publish:function(what){
        for(var i=0; i<this.subscribers.length;i++){if(typeof this.subscribers[i]==='function'){this.subscribers[i](what)}}
      },
      make:function(o){
        for(var i in this){o[i]=this[i];o.subscribers=[]}
      }
    }
    //接下来我们创建一些订阅者,它们可以是任意对象,唯一职责就是在发生重要事件时调用publish方法
    var blogger={
      writeBlogPost:function(){var content='今天是'+new Date();this.publish(content);}
    }
    var latimes={
      newIssue:function(){var paper='火星人来地球了!';this.publish(paper);}
    }
    //它们都很容易转变为发行商
    observer.make(blogger);
    observer.make(latimes);
    //于此同时,准备两个简单对象
    var jack={
      read:function(what){console.log('我刚看了'+what)}
    }
    var jill={
      gossip:function(what){console.log('你没听到我的话,但'+what)}
    }
    //将他们订阅blogger,只需要提供事件发生时的回调函数
    blogger.addSubscriber(jack.read);
    blogger.addSubscriber(jill.gossip);
    //当blogger写了新的博客时,jack和jill都会收到通知
    blogger.writeBlogPost();
    //任何时候jill都可以取消订阅,再推送时将不再收到通知
    blogger.removeSubscriber(jill.gossip);
    blogger.writeBlogPost();
    //jilly也可以订阅latimes,因为一个订阅者可以对应多个发行商
    latimes.addSubscriber(jill.gossip);
    latimes.newIssue()

     --完--

  • 相关阅读:
    Yii增删改查
    10个超级有用、必须收藏的PHP代码样例
    yii源码分析I、II
    Yii源码阅读笔记
    Yii源码阅读笔记
    Yii源码阅读笔记
    当浏览器输入url的时候发生了什么
    js模块化值之seaJS
    js判断字符串中的英文和汉字
    display:table-cell的惊天作用,直接惊呆你!
  • 原文地址:https://www.cnblogs.com/gulei/p/6273076.html
Copyright © 2011-2022 走看看