• 《javascript高级程序设计》第二版 读书笔记


    第一章   JavaScript简介

    一、javascript组成部分

    1、核心(ECMAScript)      2、文档对象模型(DOM)        3、浏览器对象模型(BOM)

    第二章    HTML中使用JavaScript

    一、<script>元素

    <script>的5个属性:

    1、charset:表示通过src属性指定的代码字符集。

    2、defer:表示脚本可以延迟到文档完全被解析和显示之后在执行。只有IE支持

    3、src:文件路径

    4、type:表示使用脚本语言的类型,<script>默认的是text/javascript,所以可以不用写.

    使用<script>的两种方式:

    1、内嵌

      可以写直接写到html文档中,<script> ... </script>

    2、引用外部

      通过src来引用外部的js文件,好处是通过src加载一次可以缓存到机器中,从而减少了服务器的压力

      <script src="...."></script>

    二、标签的位置

      引用在<head>中:引用在head标签中页面的css也会在这里引用,页面上来会载入css和javascript的文件,javascript在下载到浏览器后会进行解析和执行,在这个过程中会导致延迟,这样页面会一片空白等javascript解析完后在往下执行代码,

      所以避免这个问题一般会把javascript放到</body>之前,这样在解析javascipt之前先将页面的内容呈现出来,令用户感觉页面打开的速度也快了.

    三、延迟脚本

      这个属性用途表明脚本在执行时不会影响页面的构造,与将javascript文件放到</body>之前一个意思,但这个属性有兼容性问题

          <script src=”” defer = “defer”></script>

    四、不推荐使用的语法

      <script><!--

          ...... 

        --></script>

      加入<!--  -->注释,这个是当初了为解决一些不支持javascript的浏览器,但现在所有浏览器都支持,所以就没必要加入

    五、嵌入代码与外部文件

      在HTML中内嵌代码虽然没有问题,但还是建议使用外部文件,这样的目的

      1、代码可维护    2、文件可缓存    3、可适应未来

    六、文档模式

      IE5.5引入了文档模式的概念,最初的文档模式有:混杂模式标准模式

      混杂模式会让ie的行为与ie5相同,而标准模式让ie的行为更接近标准行为。

            

         标准模式:

             <!—HTML 4.01 严格模式 -->

             <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “html://www.w3.org/tr/xhtml1/DTD/xhtml1-strict.dtd”>

     

             <!—HTML XHTML 1.0 严格型 -->

             <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “html://www.w3.org/tr/xhtml1/DTD/xhtml1-strict.dtd”>

        <!—HTML XHTML 1.0 过渡型 -->

             <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “html://www.w3.org/tr/xhtml1/DTD/xhtml1-strict.dtd”>

         <!—HTML XHTML 1.0 框架型 -->

             <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Framest//EN” “html://www.w3.org/tr/xhtml1/DTD/xhtml1-strict.dtd”>

             IE8引入了一个叫做“超级标准模式”,标准模式使用IE7呈现的引擎,而超级标准模式则是IE8的默认文档模式,可以在IE8使用<meta>值可以关闭其默认文档模式。

             <meta http-equiv=”X-UA-Compatible” content=”IE=7” />

    五、<noscript>元素

      如果浏览器不支持javascript或者支持被禁用时,就会执行<noscript>元素,但现代浏览器基本支持.

      <noscript>

         <p>浏览器不支持javascript</p>

      </noscript>

    第三章   基本概念

    一、语法

      1、区分大小写:var test和 var Test是两个变量

      2、标识符:指的是变量的名和函数、属性或参数的名符

            第一个字符必须是字母、_、或$符号,可以使用驼峰格式,如:firstServer

      3、注释: // 单行注释    /*  多行注释 */

      4、语句:var min = a + b; 如果没有最后的分号也是正确的,但不推荐这么写 var min = a + b

            if(a==0){ ....  }

            if(a == 0)    // 没有花括号也是可以的,但不推荐这样写,容易出错

             alert("正确")

    二、变量:

      1、ECMAScript变量是松散类型,所谓松散类型就是可以存储任何值,可以是变量、字符串、函数、对象。

          定义变量时使用var,如果不使用var来创建变默认成全局变量

          function test(){

            message = "hi";

          }    alert(message);    // 这时候还是会弹出hi

       2、局部变量:在函数中使用的变量是局部变量,外界不可调用局部变量,这个变量在函数执行完退出后会自动销毁,释放内存。

          funciton test(){

            var message = "hi";    // 局部变量

          }

          test();

       3、定义多个变量可以使用逗号分开:var messgae="hi", found = false,  max = 20; 这样可以提高可读性

    二、数据类型

      1、ECMAScript有五种数据类型:整型、字符型、布尔型、undefined、null,function

      2、typeof操作符,检测变量的数据类型,String、number、boolean、null,undefined、function、object

          1) undefined:在使用一个变量未初始化时,这个变量的值就是undefined,调用未定义的变量时会报错显示 is not undefined,注意:值是undefined和报undefined的错误是不同的.

              var message;

              if(message === undefined){

                alert("成功")

              }

          2) null:null表示一个空对象的指针

              var obj = null;  alert(typeof obj);    // 返回object一个对象

              注意:if(undefined == null) // 返回的是true  if(undefined === null)  // 返回的是false      

          3) boolean:布尔,两个值true和false

          4)number:来表示整数和浮点数,

              NaN:非数值,isNaN()如果不是非数值返回true

                alert(isNaN(NaN));    // 返回true;

                alert(isNaN(10));      // 返回false;

              alert(isNaN("10"));    // 返回false可以初转成数值10

              alert(isNaN("aaa"));    // 返回true;

              alert(isNaN(true));     // 返回False 可以将true将成1

            5)三个函数可以把非数值转成数值:Number()、paresInt()、paresFloat();

          6)String:字符串可以用"和'号

              转成字符串:1、var age = 111;  age.toString();  

                    2、 var num = 10; num.toString();   // 返回"10"

                      var num = 10; num.toString(2);  // 返回二进制

                      var num = 10; num.toString(8);  // 返回八进制    还可以返回十进制、十六进制

          7)Object:

    隐式类型转换

      alert(200 == "200");    // 输出true;

      alert(200 === "200");   // 输出false;

    三、操作符

      1、一元操作符:递增和递减,i++, i--

      2、布尔操作符: 1、!逻辑非,如果表达式为真则返回假,否则返回true

    四、布尔操作符

      1、!逻辑非,如果为真结果为假             2、&& 逻辑与  表达式两端都为真返回为真               3、|| 逻辑或 表达式两端有一个为真返回为真

    五、基础操作符

      1、运算操作符:+ 加、 - 减、 *  乘、 / 除、 % 求余

      2、关系操作符:小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)、全等于(===)、不全等于(!==)

      3、逗号操作符:var a=0, b=1, c=2; 一个语句中可以执行多个操作.

    六、语句:

      1、if... else... :

      2、do... while...:是一种后测试语句,先执行循环体的内容在去看是否满足条件。

      3、while:循环语句,前测试语句,先判断是否满足条件在执行语句。

      4、for:也是前测试语句,for( ; ;)一个死循环

      5、for... in ..:迭代语句,可以用来枚举对象的属性,

      6、break:结束循环

      7、continue:结束此次循环继续下一次循环

      8、switch() ... case:流控制语句

    七、函数:

      函数可以封装任意条语句,可以在任何地方调用它使用function来声明

      1、arguments对象,将函数参数做为一个数组返回

      function add(a, b, c){   arguments.length; }  // 返回2  也可以arguments[1]来访问参数b

      2、函数重载

        重载,就是同时存在两个名称相同的函数,但它们的接收参数不同或返回值不同;在JAVA中经常会遇到.但在JS中,如果同时存在两个相同的名字的函数,它不会引发错误,但它会真正使用最后一个

        例: function add(a) { return a + 100 }  

             function add(a) { return a + 200 }

           add(100);    // 返回300

      3、return语句:函数返回值

     1 function a(){
     2     var b = 10;
     3     var c = 'abc';
     4     return 5 + 6;
     5     alert('abc');
     6 }
     7 
     8 a();    // 不会输出abc
     9 
    10 return : 函数返回值。
    11     1, 给函数赋一个值。    
    12     2, 当函数中碰到return,就会直接跳出函数,不再执行return后面的任何代码。

     

    第四章   变量、作用域和内存问题

    一、基本类型和引用类型

      变量有两种不同类型的值:基本类型和引用类型

      基本类型:指保存在栈内的简单数据断,这种值完全保存在内存的一个位置.

      引用类型:指保存在堆内存中的对象,意思是变量保存实际上是一个指针,这个指针指向内存的另一个位置. 

    二、动态属性也是对象属性

    1 var person = new Object();
    2 person.name = "nice";
    3 alert(person.name);         // 返回nice

      将一个对象保存在变量中,增加一个name属性并赋值为”nice”,如果对象不被销毁这个值也不会被删除,这个属性将一直存在。

      删除对象属性delete person.name;

    三、复制变量值

      如果一个变量向另一个变量赋基本类型值,会在栈中创建一个新值,然后把该值复制到新的变量分配的位置

    1 var obj1 = {"name": 11, "age": 22};
    2 var obj2 = obj1;
    3 obj2.name = "haha";
    4 
    5 console.log(obj1);        // obj1和obj2都为{"name": "haha", "age": 22};

    四、参数的传递

             参数的传递其实就是变量之间的传递

    五、检测类型

             1、typeof 检测数据类型(基本数据类型)

             var  str = “sss”;

             alert(typeof  str);            // 返回String

             如果typeof检测引用数据类型就不管用了,也就是对象,使用instanceof

             2、instanceof 检测变量是否是引用类型,也就是对象的属性和方法,如果是返回true;

     1 function Parane(){
     2 
     3 };
     4 
     5 var obj = new Parane();
     6 obj.name = "aa";
     7 obj.say = function(){
     8     alert("bb");
     9 }; 
    10 alert(obj instanceof Parane);            // 返回true

    六、变量作用域

    1、变量声明:如果变量在未经声明的情况下创建会认为是全局变量

     1 function add(n1, n2){
     2       var sum = n1 + n2;            // 如果用var 声明变量,变量存在于函数的局部
     3       return sum;
     4 }
     5 
     6 var res = add(10, 20);
     7 alert(sum);     // 返回错误没有这个变量
     8 
     9 function add(n1, n2){
    10       sum = n1 + n2;          // 如果不用var来声明变量,执行完add()后会将sum增加到全局中.
    11       return sum;
    12 }
    13 
    14 var res = add(10, 20);
    15 alert(sum);    // 返回30
     1 例1:
     2 var a = 1;
     3 function fn1(){
     4     var a = 5;
     5     alert(a)        // 输出5
     6 }
     7 fn1();
     8 
     9 
    10 例2:
    11 var a = 1;
    12 function fn1(){
    13     var b = 4;
    14     fn2();
    15     a = b;
    16     function fn2(){
    17         alert(b);        // 4
    18         alert(a);        // 1
    19     }
    20 }
    21 fn1();

    2、搜索标识符

    也就是查找变量,当用到一个变量时会查找这个变量的实际代表什么,搜索过程从作用域开始查找,逐级向上查找,

    1 var color = “blur”;
    2 function getColor(){
    3      var color = “rad”;
    4      return  color
    5 }
    6 
    7 getColor();        // 返回rad  *查找局部变量要比全局变量要快*  

    七、拉圾回收机制

          Javascript的所需内存的分配和无用内存的回收实现了自动管理

      局部变量的生命周期:

            函数中的局部变量只在函数执行中存在,会在栈或堆内存中分配一块空间,到函数执行结束时,些时局部变量就会自动销毁.

    八、内存管理

      分配给web浏览器的内存要比桌面内存要少,处于安全问题,防止运行javascript的网页耗尽内存使系统崩溃

      为了确保性能,优化的最佳方式,就是执行中的代码保存有用的数据,一旦没有用就将其设置为null来释放引用,这个方法叫解除引用。这个做法适用于全局变量和对象属性,局部变量它们在函数执行完后自动被解除引用.

    九、加载和执行,从编辑到可执行的代码

      1、变量引用的执行顺序

      alert(i);    // undefined

      var i = 10; 

      2、函数的执行顺序

      test();    // a

      function test(){ alert("a") }    // 会将test函数进行预编辑

      3、函数重载 

    1 test()      // 输出b 因为函数预存,并且函数重载 
    2 function test(){ alert("a") }
    3 var test = function(){ alert("s"); }
    4 function test(){ alert("b") }
    5 
    6 test()      // 输出s
    7 test();       // 输出s 

     

    第五章 引用类型

    引用类型是一种数据结构,引用类型也被称为对象定义,

    var peron = new Object();       创建Object的引用类型的一个新实例,把它保存在peron变量中,它只为新对象定义了属性和方法。

    一、引用

      引用实际就是指向对象实际位置的指针.

      几个变量指向同一个对象时,其中一个改变了对象的变量,这种改变是全局的,另一个也会受到影响.

     1 <script>
     2     var obj = {
     3         arg: 0,
     4         show: 1
     5     }
     6 
     7     var n1 = obj;
     8     var n2 = obj;
     9 
    10     n1.age = 10;
    11     alert(n2.age);        // 10 
    12     alert(n2.show);        // 1
    13 </script>
    1 <script>
    2     var items = new Array( "one", "two", "three" );
    3     var itemsRef = items;
    4     //给原始数组添加一项
    5     items.push( "four" );
    6     alert( items.length == itemsRef.length );      // 相等
    7 </script>

    一、Object类型

    大多数引用类型都是object类型的实例.

    创建object实例的两种方法:

    1、  new

    1 var peron = new Object();
    2 peron.name = "aaaa";
    3 peron.age = "bbbb";

    2、  对象直接量 {}

    1 var peron = {  // 与var peron = new Object()相同
    2 
    3   name : "aaaa",
    4   age : "bbbb" 
    5 }

    ----还有一种写方法

    1 var peron = {};    // 与var peron = new Object()相同
    2 peron.name = "aaaa";
    3 peron.age = "bbbb";

    ----直接量也是向函数传大量可选参数的首选

     1 例如:
     2 
     3 function displayInfo(args){
     4     var output = "";
     5     if(typeof args.name){
     6          output = "属性是字符串"
     7   }
     8   return output;
     9 };
    10 
    11 displayInfo({
    12     name : "aaa",
    13     age : "29"
    14  });

    二、Array类型

      创建数组:

      1、 arr = new Array()  2、arr = new Array('red', 'blur', 'green');    3、arr = ['red', 'blue', 'grren'];

    三、Function类型

    函数实际上是一个对象,每个函数都是一个Function类型的实例

    为什么可以写匿名函数,说白了就是函数也是对象,与引用类型一样具有属性和方法,由于函数是对象,所以函数名实际上也是函数的指针

    定义方法:

    1 funciton sum(n1, n2){    // 方法一
    2   return n1 + n2;     
    3 }
    4 
    5 var sum = function(n1, n2){  // 方法二
    6     return  n1 + n2;
    7 }

    --- 另一种函数定义函数的方式是使用Function 构造函数,Function构造函数可以接受任意参数,但最后一个参数为函数主体,不过此方法不推荐

    var newFun = Function("n1", "n2", "return n1 + n2");    // 这种方法会导致解析两次
    alert(newFun(10, 20));
    

     

    四、函数的内部属性

      arguments:一个数组,奖参数传入这个数组中。

    五、call和apply

      调用指定的函数,也可以方法能劫持另外一个对象的方法,继承另外一个对象的属性.

      两者的区别是call需要将函数的参数列出来,apply第二个参数是一个数组

     1 function fun1(num1, num2){
     2     return num1 + num2;
     3 }
     4 
     5 function fun2(num1, num2){
     6     return fun1.call(this, num1, num2);
     7 }
     8 
     9 function fun3(num1, num2){
    10     return fun1.apply(this, arguments);
    11 }
    12 
    13 
    14 var num = fun2(20, 50);
    15 var num1 = fun3(100, 200);
    16 console.log(num);        // 70
    17 console.log(num1);        // 300

    第六章  面向对象的程序设计

    一、创建对象

    1 var Person = new Object();
    2 Person.name = “haha”;    // 对象属性
    3 Person.age = 29;      
    4 Person.sayName = function(){ // 对象方法
    5          alert(this.name);
    6 }

    创建一个对象,添加了两个属性和一个公用函数

    1、、销毁对象

      var Person = new Object();

      Person.name = “haha”;    // 对象属性

      Person.age = 29;

      Person = null;    // 将对象消毁

    2、删除对象的属性

      var Person = new Object();

      Person.name = “haha”;    // 对象属性

      Person.age = 29;

      delete Person.name;  //删除name属性

    二、设计模式

    1、工厂模式:用函数来封装,以特定的接口创建对象的

     1 function createPerson(name, age, job){
     2         var o = new Object();
     3         o.name = name;
     4         o.age = age;
     5         o.job = job;
     6         o.syaName = function(){
     7             alert(this.name);
     8         };
     9         return o;
    10 };
    11 
    12 var Person1 = createPerson("nn", 29, "sofeware Exgineer");
    13 Person1.syaName();

     

    2、构造函数模式:

    象Object和Date之类的内置对象,构造函数也是函数,但需要new来创建

     1 function Person(name, age, job){
     2     this.name = name;
     3     this.age = age;
     4     this.job = job;
     5     this.sayName = function(){
     6         alert(this.name);
     7     }
     8 }
     9 var person1 = new Person("哈哈", 20, 0);
    10 Person("啊啊", 21, 0);  // 这种调用就需要window.syaName();
    11 person1.sayName();
    12 
    13 // 在另一个对象中调用
    14 var o = new Object();
    15 Person.call(o, "可呆", 100, 100);
    16 o.syaName();

    3、  原型模式:

    每一个函数都有一个prototype原型属性,这个属性是一个对象,用途是包含可以由特定类型的所有实例共享的属性和方法

    1 function Person(){}
    2 
    3 Person.prototype.name = "sss";
    4 Person.prototype.syaName = function(){
    5     alert(this.name);
    6 }

    三、继承

    许多oo语言都支持两种方式:接口继承 和 实现继承

    1、只继承方法:

     1 function ClassA(name){
     2     this.name = name;       // 通过参数赋给属性的不可以继承
     3     // this.name = 20;        // 这种可以继承 
     4 }
     5 
     6 ClassA.prototype.sayName = function(){
     7     console.log(this.name);
     8 }
     9 
    10 function ClassB(age){
    11     this.age = age;
    12 }
    13 
    14 ClassB.prototype = new ClassA();
    15 
    16 ClassB.prototype.sayAge = function(){
    17     console.log(this.age);
    18 }
    19 
    20 var newClassA = new ClassA("lulu");
    21 var newClassB = new ClassB(20);
    22 newClassA.sayName();        // undefinded
    23 newClassB.sayAge ();          // 20        

    可以通过call来继承属性

     1 function ClassA(name){
     2     this.name = name;
     3 }
     4 
     5 ClassA.prototype.sayName = function(){
     6     console.log(this.name);
     7 }
     8 
     9 function ClassB(name, age){
    10     ClassA.call(this, name);    // 继承属性
    11     this.age = age;
    12 }
    13 
    14 ClassB.prototype = new ClassA();  // 继承方法
    15 
    16 ClassB.prototype.sayAge = function(){
    17     console.log(this.age);
    18 }
    19 
    20 var newClass = new ClassB("lulu", 20);
    21 newClass.sayAge();
    22 newClass.sayName();

    ECMAScript只支持实现继承.

    1、  原型链

    实现原型链的一种基本模式:

     1 function VideoFirst(){  // 创建对象1
     2     this.name = "aa";
     3 };
     4 
     5 VideoFirst.prototype.syaName = function(){
     6     alert(this.name);
     7 };
     8 
     9 function VideoSecnd(){  // 创建对象2
    10     this.say = "bb";
    11 };
    12 
    13 //  VideoSecnd继承了VideoFirst;
    14 VideoSecnd.prototype = new VideoFirst();
    15 
    16 var newVideo = new VideoFirst();
    17 newVideo.syaName();         // 返回 aa
    18 
    19 var newVideo1 = new VideoSecnd()
    20 newVideo1.syaName();        // 返回 aa
    21 
    22 // 超生类
    23 // 重新syaName函数,叫超生类
    24 VideoSecnd.prototype.syaName = function(){
    25     alert("bb");
    26 };
    27 
    28 var newVideo2 = new VideoSecnd();
    29 newVideo2.syaName();    // 返回 bb

    第七章  匿名函数

          匿名函数就是没有名字的函数,也称为拉姆达函数

    一、函数声明

    1、声明函数:

    1 function functionName(age0, age1, age2){    // 声明函数调用可以在任意位置
    2     alert(“aa”);
    3 };

    2、  将一个函数表达式结果返回给一个变量:

    1 var functionName = function(){        // 调用函数表达式必须在之后
    2   alert(“aaa”);
    3 }

    3、  创建一个匿名函数并执行

    1 (function(n){
    2     Alert(n)
    3 })(“20”);

    4、  还可以这么写:但这种函数是没法调用的

    1 function(age1, age2, age3){
    2       alert(“bbb”);
    3 }

    二、递归

      递归函数是在一个函数内在调用这个函数本身

     1 <script>
     2     var num = 100;
     3     function factorial(){
     4         num -= 1;
     5         if(num <= 0){
     6             alert("已经为0");
     7         }
     8         else{
     9             console.log(num);
    10             factorial();
    11         }
    12     }
    13 
    14     factorial();
    15 </script>

    三、闭包

      闭包:是有权访问另一个函数作用域中变量的函数

      一般局部变量会在函数结束时而自动销毁,而闭包里的变量不会销毁,所以易导致内存泄漏.

    1 function comp(){
    2     var name = "aa";
    3     return  function(){
    4         alert(name);    // 可以访问name,外部函数是无法访问函数内部变量的
    5     }
    6  }    

      1、什么是闭包:函数嵌套函数,内部函数可以引用外部函数的变量,参数和变量不会被拉圾回收机制所收回

    一个简单的闭包:

     1 function aa(a){
     2     var b = 5;
     3     function bb(){
     4         alert(a);
     5         alert(b);
     6     }
     7    return bb;
     8 }
     9 
    10 var c = aa(5);
    11 c();

       

    2、闭包的好处:1)希望一个变量长期在内在中     2)避免全局变量的污染  3)私有成员的存在

     1 如果想a来存储累加,但又不想超成全局的污染,这时候可以使用闭包,
     2 如果不需要a累加存储数据,直接放到函数内部做局部变量就好了
     3 <script>
     4     var a = 1;
     5     function aa(){
     6         a++;
     7         alert(a);
     8     }
     9 
    10     aa();    // 2
    11     aa();    // 2
    12     alert(a);
    13 </script>
    14 
    15 
    16 将上面改成闭包的形势
    17 <script>
    18     function aa(){
    19         var a = 1;
    20         return function(){
    21             a++;
    22             alert(a);
    23         }
    24     }
    25 
    26     var cc = aa();
    27     cc();    // 2
    28     cc();    // 3
    29 </script>

    3、闭包的用法: 1)模块化代码 

     1 <script>
     2     var aa = (function(){
     3         var a = 1;      // 私有变量
     4         
     5         function bb(){  // 私有函数
     6             alert(a);
     7         }
     8         
     9         return function(){  // 公有函数
    10             a++;
    11             alert(a);
    12         }
    13     })();
    14 
    15     aa();
    16     aa();
    17 </script>

    4、闭包需要注意的: 1)在IE下会引发内存泄露

     1 <script>
     2     // 内存泄露会导致cpu的运算增加,内存不断的累加页面会死掉,或者缓慢
     3     // 产生内存泄露:一个对象调用事件后,内部函数又调用了这个对象的属性或方法,这样互相调用会导致内存泄露
     4     var box = document.getElementById("box");
     5     box.onclick =  function(){
     6         alert(box.id);      // 这种会产生内存泄露
     7     }
     8 
     9     // 解决方法一:使用后将对象清除
    10     var box = document.getElementById("box");
    11     box.onclick = function(){
    12         alert(box.id);
    13     }
    14     window.onunload = function(){
    15         box.onclick = null;     // 清除对象引用
    16     }
    17 
    18     // 解决方法二:避免内部引用
    19     var box = document.getElementById("box")
    20     var oId = box.id;
    21     box.onclick = function(){
    22         alert(oId);     // 将要引用的属性存放在外部变量中
    23     }
    24 </script>

    拉圾回收机制,当函数执行完后变量就会被拉圾回收机制所收回,这样来节省内存

    function create(){ var a = "1111"; }

    create()

    三、内存泄漏

    闭包在IE中会导致一些问题,闭包作用域中保存着HTML元素,那么就意味着该元素的该元素将无法被销毁。

     1 function assignHandler(){
     2     var element = document.getElementById("some")
     3     element.onclick = function(){
     4         alert(Element.id);
     5     }
     6 }
     7 
     8 // 获取一个元素,在闭包内调用了元素的属性,IE就会存在内存泄漏
     9 
    10 解决方法:
    11 
    12 function assignHandler(){
    13     var element = document.getElementById("some")
    14     var getId = element.id;             // 获取放到下面
    15     element.onclick = function(){    // 这个闭包创建了死循环引用
    16         alert(getId);
    17     }
    18     element = null;                   // 将获取的对象为空
    19 }

    四、解除对匿名函数的引用(释放内存)

    var compareName= createCompareName();

    compareName = null;  // 解除引用

    五、this对象

      在全局函数中,this指象的是window

     

    六、私有变量

    Javascript没有私有成员的概念,所有对象的属性都是公有,不过有私有变量的概念。

    任何函数内的变量都是私有,因为外部不可以调用。

    1 function add(num1, num2){
    2   var sum = num1 + num2;
    3   return sum;               // num1, num2, sum都是私有变量
    4 };

    1、  特权方法:我们把有权访问私有变量和私有函数的公有方法称为特权方法。 

     1 function MyObject(){
     2         var ss = "aaa";   // 私用变量
     3 
     4         function privateFun(){
     5             return false;
     6         }; 
     7 
     8         this.publicMyObject = function(){  // 特权方法
     9             alert(ss);
    10         };
    11 } 
    12 var createMy = new MyObject();
    13 createMy.publicMyObject();   // 通过构造函数的公用方法来调用私有变量

       

    五、静态私有变量

      通过在私有作用域中定义了私有变量或函数,

    六、模块模式

    模块模式是为单例创建私有变量和特权方法,

    所谓单例,指的就是一个实例的对象。

    创建一个模块模式:

     1 var singleton = {
     3     name : value,
     5     method : function(){
     7          alert(“aa”)
     9   }
    10 };

    另一种单例,有私有属性和方法

     1 var singleton = function(){
     2     // 私有变量和私有函数
     3     var privateVar = 10;
     4 
     5     // 私有函数
     6     function privateFun(){
     7         return false;
     8     }
     9 
    10     // 返回对象,可以通过特权方法来访问私有属性和私有方法
    11     return {
    12         publicVar : 10,
    13         publicMethod : function(){
    14             privateVar++;
    15         }
    16     }
    17 }()
    18 
    19 singleton.publicMethod();

     

    第八章  BOM 浏览器对象模型

    一、Window对象

             BOM的核心是window对象,它表示浏览器的一个实例。

             网页的任何一个对象、变量和函数,都以window作为其Global对象,

             全局作用域:

             全局作用域中声明的变量、函数都会变成window对象的属性和方法。

    1 var age = 29;
    2 
    3 function syaAge(){
    4   aert(this.age);
    5 };
    6 
    7 alert(this.age);         // 29
    8 syaAge();          // 29
    9 window.syaAge();    // 29

     

    二、窗口位置

             1、浏览器窗口距屏幕左、上的位置:window.

        screenLeft、screenTop:兼容IE、Safari、Opena、Chome,注:ie是以客户区域而不是浏览器窗口为准

        screenX、ScreenY:FF下兼容

            

             2、移动窗口window

        moveTo(x,y):将窗口移动距屏幕x,y轴的位置

        moveBy(x,y):以当前窗口位置,将窗口移动多少像素

         3、窗口大小window

             Window.innerWIdth、window.innerHeight、window.outerWidth、window.outerHeight:兼容FF、Safari、Opena、Chome

             注:innerWIdth、innerHeight、outerWidth、outerHeight中FF、Safari返回浏览器本身窗口

             4、获取客户端区域大小:document

             clientWidth、clientHeight:

             document.documentElement.clientWidth;

             document.body.clientWidth;

            

             5、调整浏览器窗口宽、高window

             resizeTo(w, h):

             resizeBy(w, h):

    三、window其它方法

             1、window.open(),window.close():打开和关闭窗口

             2、window.setInterval(fn, timer):按规定的时间不断的执行函数

         window.setTimeout(fn, timer):按规定的时间只执行一次

         window.clearIntervall()、window.clearTimeout();

               

    四、location对象

      提供了窗口中加载文档的相关信息

      location它既是window对象的属性也是document对象的属性,window.location和document.location引的同一个对象

      属性和方法:

      1、hash:返回url中的“#”号之后的字符串,如果url中没有#返回空字符串

      2、host:返回端口号, wan.renren.com:8080  返回8080

      3、hostname:返回主机名称,wan.renren.com

      4、pathname:返回目录或文件名称,wan.renren.com/pay/login/   返回/pay/login

      5、port:返回url中指定的端口号

      6、protocol:返回页面使用的协议,如http:或https:

      7、search:返回url查询的字符串,“?a=javascript”

    五、history对象

      history保存着用户上网的历史记录,从窗口被打开算起。

      1、  go():通过go方法可以在用户历史记录中任意跳转

      history.go(-1):后退一页

      history.go(1):前进一页

      history.go(2):前进两页

      2、back():后退一页

               

    第九章  客户端检测 

    一、能力检测:测试浏览器是否支持

        例:ie5.0不支持document.getElementById()

     1 var getid;
     2 
     3 if(document.getElementById){
     4   getid = document.getElementById("obj");
     5 }
     6 else if(document.all){        // ie5.0以下
     7   getid = document.all["obj"];
     8 }
     9 else{
    10   alert("浏览器不支持获取id元素")
    11 }

    二、怪癖检测:

             与能力检测类似,目的是识别浏览器的特殊行为,与能力检测的区别是,怪癖检测要知道浏览器的缺陷在哪

     

    三、用户代理检测

    第十章  DOM

    一、动态脚本

             动态脚本指的是在页面加载进不存在,但某一时段通过修改DOM动态添加的脚本。

             创建动态脚本有两种方式:插入外部文件和直接插入javascript代码

     1 function loadScript(url){
     2         var script = document.createElement("script");
     3         script.type = "text/javascript";
     4         script.src = url;
     5         document.getElementsByTagName("body")[0].appendChild(script);
     6 
     7 };
     8 
     9 var scrStr = "http://img.wan.renren.com/vcms/js/new-wan-2/base.js";
    10 loadScript(scrStr);

    二、动态样式   

     function loadCSS(url){
    
            var css = document.createElement("link");
    
            css.type = "text/css";
    
            css.rel = "stylesheet";
    
            css.href = url;
    
            document.getElementsByTagName("head")[0].appendChild()
    
    }
    

             动态加载外部文件的过程是异步的,也就是加载的内容与固定页面的内容加载没有次序

    三、表格

          1、rows:表格的所有行

          2、cells:保存着<tr>元素中的单元格

    第十一章   事件

    一、事件流

             事件流描述页面中接收事件的顺序,IE的事件流就是事件冒泡流,Netscape的事件流是事件捕获流.

    1、 事件冒泡:

      IE的事件流叫事件冒泡,事件开始由具体的元素接收,然后逐级向上传播

          <html>

    <head>

    <title>无标题文档</title>

    </head>

    <body>

             <div id="box">demo</div>

    </body>

    </html>

      如果点击box时会按照如下顺序:

      <div>-<body>-<html>-document  会沿着DOM树一直传播到document对象

    2、事件捕获:

             Netscanp提出了另一种事件流叫事件捕获。

             拿上面的例子来说:

             如果点击box时会按照如下顺序:

             document-<html>-<body>-<div>  与事件冒泡正好相反

    3、事件流:

             事件流包括三个阶段:事件捕获、处于目标和事件冒泡

             Opear、chrom、ff、Safari都支持DOM事件流,IE不支持DOM事件流

    二、事件处理程序(或事件侦听)

      1、HTML事件处理程序:<div onclick="alert('aaa')"></div>

      2、DOM事件处理:先取得操作对象的引用

    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        alert(this.id);
    }
    
    btn.onclick = null;         // 删除事件处理程序
    

      事件就是用户在浏览器作出的行为,如click、load和mouserove等,都是事件的名称,而响应某个事件的函数叫事件处理程序

    function addEvent(obj, type, fn){
        if(obj.addEventListener){
            obj.addEventListener(type, fn, false);     // 标准DOM下事件侦听
        }
        else{
            obj.attachEvent("on" + type, fn);             // IE下事件侦听
        }
    };
    
    注:如果fn为闭包,则不能移出侦听,也就是
    
    Obj.addEventListener(“onclic”, function(){ ….. }, false);           // 这种是无法用removeEventListener移除
    

    三、事件对象

      在DOM触发某个事件时,会产生一个事件对象Event,这个对象包含所有事件的信息

    四、事件类型

    事件类型有五种:

    1、  UI(用户界面)事件,在用户与页面上的元素进行交互.

    2、  鼠标事件:用户通过鼠标在页面上执行的操作

    3、  键盘事件:用户通过键盘在页面上执行的操作

    4、  HTML事件:当浏览器窗口在发生变化或发生特定的客户端、服务器端交互时触发

    5、  变动事件:当底层的DOM结构发生改变时触发.

    UI主要与元素的焦点有关,有三个UI事件

    1、  DOMActive:操作元素已被用户操作(通过鼠标或键盘)所激活。

    2、  DOMFocusIn:元素已经获得了焦点,HTML中focus

    3、  DOMFocusOut:元素已经失去了焦点,HTML中focus

    鼠标事件:

    1、  onclick:点击

    2、  ondbclick:双击左键

    3、  onmouseup:鼠标抬起

    4、  onmousedown:鼠标按下

    5、  onmouseover:移到指定元素中

    6、  onmouseout:移出指定的元素

    7、  onmousemove:在指定的元素中移动所触发

    8、  clientX、clientY:客户区域的x、y轴

    9、  screenX、screenY:屏幕坐标的x、y轴

      鼠标和按键的组合键:

    shiftKey、ctrlKey、altKey、metaKey:如果相应的按下时会返回true       

    box.onclick = function(event){
            var evt = RGEvn.getEvent(event);
    
            if(evt.shiftKey){
                alert("已按下shift和鼠标左键");
            }
    if(evt.altKey){ alert("已按下alt和鼠标左键"); } if(evt.ctrlKey){ alert("已按下ctrl和鼠标左键"); } if(evt.metaKey){ alert("已按下Cmd和鼠标左键"); } }

      鼠标按钮:

      button属性:

          DOM下的button属性返回值:1左键  2中键(滚轮)  3右键

          IE下的button属性返回值:0没有按下按键     1按下左键      2按下右键   3同时按下左右键  4

    键盘事件:

    1、  keydown:按下按键

    2、  keypress:按下按键

    3、  keyup:释放按键

    4、  testInput:用户在可编辑区输入

    键盘码:keyCode

    在keyup、keydown时,event对象的keyCode属性中会包含一个代码,

     document.onkeyup = function(event){
         evt = event || window.event;
         box1.innerHTML = evt.keyCode;
    };
    

    HTML事件:

    1、  load:当页面加载(包括图片、javascript文件、css等资源)后会触发window上面的load事件

    2、  unload:当页面卸载后在window上触发

    3、  abor:当用户停止下载过程时

    4、  error:当发生javascript错误时在window触发

    5、  resize:窗口或框架的大小改变时触发

    6、  scroll:滚动条滚动时触发

    7、  select:下拉菜单

    8、  change:

    9、  submit:用户提交表单时触发

    10、reset:表单重置

    11、focus:当页面或元素获得焦点时触发

    12、blur:当页面或元素离开焦点时触发

    变动事件:变动事件能在DOM中的某一部分发生变化时给出提示,变动事件是为XML和DOM设计的,

    1、  DOMSubtreeModified:在DOM结构中发生任何变化时触发,这个事件在任何事件触发后都会触发

    2、  DOMNodeInserted:在一个节点作为子节点被插入到另一个节点中时触发

    3、  DOMNodeRemoved:在节点从其父节点宫被移除时触发

    4、  DOMNodeInsertedIntoDocument:在一个节点被直接插入文档或通过子树间接插入文档之后触发.

    5、  DOMNodeRemovedFromDocument:

    6、  DOMAttrModified:在特性被修改之后触发

    7、  DOMCharacterDataModified:在文本节点的值发生变化时触发

    专有事件:

    1、 DOMContentLoaded:在形成完整的DOM树之后就会触发,不会等图像、javascript文件、css文件或其它资源是否已经下载完毕

    RGEvt.addEvent(document, “DOMContentloaded”, function(){ ….. })

    2、 contextmeun:上下文菜单事件

    3、 readystatechage:就绪状态变化事件,其实就是ajax中调用的onreadystatechange来查看数据是否加载完成,这个事件是提供与文档或元素的加载信息,readystatechage事件的每个对象都有一个readyState属性,它包括5个值。

    1、 uninitialized(未初始化):对象正在加载数据

    2、 loading(正在加载):对象下正在加载数据

    3、 loaded(加载完毕):对象加载数据完成

    4、 interactive(交互):可以操作对象了,但还没有完全加载

    5、 complete(完成):对象已经加载完毕

    五、事件委托

             对“事件处理程序过多”问题的解决方案就是事件委托,事件委托就是利用事件冒泡,只

    一些遇到的问题

    一、定时器的重复开启

    function Drag(){
        var timer = null
        var speed = 1;
        clearInterval(timer);        // 如果这块不清除那么点一次就开启一个定时器
        timer = setInterval(function(){
            $("#box").css("left", $(this).offset().left + speed);
        }, 30);
    }
    
    $("#box").click(function(){ Drag(); })
    

    二、定时器的分配与管理

    <div id="div1">
    <ul>
    	<li></li>
        <li></li>
        <li></li>
    </ul>
    </div>
    
    <script>
    function getID(id){
        return document.getElementById(id);	
    }
    
    var obj = getID("div1");
    var oLi = obj.getElementsByTagName("li");
    var speed = 0;
    
    for(var i=0; i<oLi.length; i++){
        oLi[i].timer = null;        // 为每个元素定义一个定时器的引用
        oLi[i].onmouseover = function(){
            startMove(this, 500)
        }
        
        oLi[i].onmouseout = function(){
            startMove(this, 100);
        }
    }
    
    function startMove(element, target){
        clearInterval(element.timer);
        element.timer = setInterval(function(){    // 如果在这只开一个定时器,若第一个还没有执行完,在执行第二个就会将定时器停止重新开启第二个定时器
            speed = (target - element.offsetWidth) / 8;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            console.log(element.offsetWidth +" "+ target + " " + speed);
            if(element.offsetWidth == target){
                clearInterval(element.timer);
            }
            else{
                element.style.width = element.offsetWidth + speed + "px";
            }
        }, 30)
    }
    </script>
    

    三、定义元素name属性值值不能为xxx-xx

    如果在jquery通过name来获取时是取不到这种属性值的,nav-first可以写成navFirst

    <input type="text" value="" name="usAgears" class="inp-t-w122">
    <input type="text" value="" name="usAgears" class="inp-t-w122">
    <input type="text" value="" name="usAgears" class="inp-t-w122">
    
    $("input[name='" + n1 + "']").each(function(){
            alert("a")    // 弹出三次
    })
    
    
    如果带值带"-"
    <input type="text" value="" name="us-Agears" class="inp-t-w122">
    <input type="text" value="" name="us-Agears" class="inp-t-w122">
    <input type="text" value="" name="us-Agears" class="inp-t-w122">
    
    $("input[name='" + n1 + "']").each(function(){
            alert("a")     // 只弹出一次
    })
    

      

    第十七章   Ajax与JSON

     1 /*
     2  * 1、readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
     3  * 0: 请求未初始化
     4  * 1: 服务器连接已建立
     5  * 2: 请求已接收
     6  * 3: 请求处理中
     7  * 4: 请求已完成,且响应已就绪
     8  *
     9  * 2、status
    10  * 200: "OK"
    11  * 404: 未找到页面
    12  * */
    13 
    14  // 创建XMLHttpRequest对象
    15 function createAjax(){
    16     var xhr = null;
    17     if(window.XMLHttpRequest){
    18         xhr = new XMLHttpRequest();
    19     }
    20     else{
    21         xhr = new ActiveXObject("Microsoft.XMLHTTP");
    22     }
    23     return xhr;
    24 }
    25 
    26 // GET请求
    27 function get(url, async, callback){
    28     var newAjax = createAjax();
    29     newAjax.open("GET", url, async);
    30 
    31     // 当请求被发送到服务器时
    32     newAjax.onreadystatechange = function(){
    33         if(newAjax.readyState === 4 && newAjax.status === 200){
    34             if(callback){
    35                 console.log(newAjax.responseText);      // 返回非xml文件,也可以请求XML文件,使用responseXML
    36                 callback();
    37             }
    38             else{
    39                 console.log(newAjax.responseText);
    40             }
    41         }
    42     }
    43 }
    44 
    45 // POST请求
    46 function post(url, dataJson, async, callback){
    47     var newAjax = createAjax();
    48     newAjax.open("POST", url, async);
    49     newAjax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    50     newAjax.setRequestHeader("If-Modified-Since","0");
    51 
    52     // 当请求被发送到服务器时
    53     newAjax.onreadystatechange = function(){
    54         if(newAjax.readyState === 4 && newAjax.status === 200){
    55             if(callback){
    56                 console.log(newAjax.responseText);
    57                 callback();
    58             }
    59             else{
    60                 console.log(newAjax.responseText);
    61             }
    62         }
    63     }
    64     newAjax.send(dataJson);         // 如果请求不需要数据参数可以为空
    65 }

    第十九章   客户端存储

    一、cookie限制

      cookie是绑定在特定的域下,

      IE6下每个域限制最后存储20个cookie,IE7下最多50个cookie

    二、cookie的组成

      1、名称  2、值  3、域  4、失效时间

      document.cookie = "name=siguang";

     

      内容使用:decodeURIComponent()、encodeURIComponent()来进行编码和解码

     1 // 存储Cookie
     2 // 如果存储时不加日期,cookie的类型为Session,否则就是结束日期
     3 function addCookie(key, val, expires){
     4     var nDate = new Date();
     5     nDate.setTime(nDate.getTime() + 1000*60*60*24*expires); // 以天为单位
     6     var sContent = key + "=" + val;
     7     var sExpires = "expires=" + nDate.toGMTString();
     8     document.cookie = sContent + ";" + sExpires;
     9 }
    10 
    11 // 获取Cookie
    12 function getCookie(key){
    13     var sCookies = document.cookie;     // 获取域下所有cookie
    14     if(sCookies.length <= 0){ return false; }
    15     var setVal = "";
    16     var arr = sCookies.split(";");
    17 
    18     for(var i=0; i<arr.length; i++){
    19         var arrJosn = arr[i].split("=");
    20         if($.trim(arrJosn[0]) === key){
    21             setVal = arrJosn[1];
    22             break;
    23         }
    24     }
    25     return setVal;
    26 }
    27 
    28 // 删除Cookie
    29 function deleteCookie(key){
    30     addCookie(key, "", -1);
    31 }
    32 
    33 // addCookie("name", "lulu", 5);
    34 // addCookie("haha", "siguang", 5);
    35 deleteCookie("name")
    36 deleteCookie("haha")
  • 相关阅读:
    生活中残忍的真相
    @ControllerAdvice 拦截异常并统一处理
    自律的人生
    50建议
    公众号自动发送红包
    增加记忆力方式
    MySQL行转列与列转行
    微人生的活法
    人生三出戏
    很重要的一点是 关注并坚持去做那些短期看不到效果,但对你影响深远的事情。
  • 原文地址:https://www.cnblogs.com/couxiaozi1983/p/2939328.html
Copyright © 2020-2023  润新知