2019.09.02 js高级程序设计 阅读笔记

132 阅读10分钟

第一章 JavaScript简介 (P1 ~ P9)

没什么太特别的内容

第二章 在HTML中使用JavaScript

  1. Q:在带有src属性的<script>标签中嵌入代码,会有什么效果?
    A:只会下载脚本,嵌入的代码会被忽略。

  2. Q:什么是延迟脚本?
    A:在<script>标签中添加defer属性,如:
    <script type="text/javascript" defer="defer"></script>
    但是,defer只适用于外部脚本。

  3. Q:什么是异步脚本?
    A:在<script>标签中添加async属性,如:
    <script type="text/javascript" async></script>
    但是,async只适用于外部脚本。并且脚本的执行顺序不能保证。

第三章 基本概念

  1. Q:js是否区分大小写?
    A:区分
  2. Q:数据类型有几种?
    A:
    1. 五种基本类型:undefined,null,boolean,number,string
    2. 一种复杂类型:object
  3. Q:检测数据类型使用什么方式?
    A:使用typeof操作符
  4. 对object或者null使用typeof操作符,返回object
  5. NaN与任何值都不相等,包括它自己,如:
    alter(NaN==NaN) //false
  6. Q:如何判断"不是数值"?
    A:使用isNaN()函数
  7. object:
    属性和方法:
    1. constructor:保存着用于创建当前对象的函数
    2. hasOwnProperty(propertyName):用于检测给定的属性在当前对象实例中是否存在
    3. isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型
    4. propertyIsEnumberable(propertyName):用于检查更定属性是否能够使用for-in来枚举
    5. toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应
    6. toString():返回对象的字符串表示
    7. valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。
  8. 布尔操作符:
    Q:使用逻辑非操作符!,哪些会返回true?
    A:空字符串、0、null、NaN、undefined
  9. with语句:将代码的作用域设置到一特定的对象中。
  10. Q:switch语句如何做范围判断?
    A:
    var num = 25;
    switch(true){
        case num < 0:
            alert(true);
        break
      }
    
  11. arguments是一个数组,用来存放函数的参数。

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

  1. Q:如何延长作用域链?
    A:
    1. try-catch语句的catch块
    2. with语句

第五章 引用类型

  1. 访问属性可以使用点表示法,也可以是用方括号表示法来访问对象的属性。
    方括号表示法的好处就是可以通过变量来访问属性。

  2. length-1 用来访问数组的最后一项

  3. 判断是否是数组,使用value instanceof Array
    也可以使用Array.isArray(value)

  4. 数组转字符串:

    1. 调用数组的toString()方法,会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。
    2. array.join("sign"),join方法不传参数,或者传入"undefined",则返回用逗号分隔的字符串
  5. 数组的栈方法:

    1. push()和pop()在数组末尾位置推入和删除
    2. unshift()和shift()在数组开始位置推入和删除
  6. array.reverse() 反转数组的项的顺序
    array.sort() 按升序方法比较得到的字符串
    array.concat()基于当前数组,创建一个新数组
    array.slice(start,end)基于当前数组中的一个或多个项创建一个新数组,原数组不变。

    1. 如果只有一个参数,则返回这个位置开始,到数组末尾。
    2. 两个参数,则返回从第一个参数开始到e第二个参数结束的数组。
      array.splice()
    3. 删除:两个参数,如splice(0,2)则会删除数组的前两项
    4. 插入:三个参数,splice(起始位置,要删除的数量,要插入的项),splice(2,0,"red"),从数组的位置2开始,插入"red"
    5. 替换:三个参数,splice(起始位置,要删除的项数,要插入的项),splice(2,1,"red"),会删除当前位置2的项,然后从位置2开始,插入"red"
  7. 位置方法,indexOf(),没有找到的情况下,返回-1

  8. 迭代方法:

    1. every()对数组中的每一项运行给定函数,如果每一项都返回true,则返回true
    2. filter()对数组中的每一项运行给定函数,返回k该函数会返回true的项组成的数组
    3. forEach()对数组中的每一项运行给定函数。这个方法没有返回值
    4. map()对数组中的每一项运行给定函数,返回每次函数调用结果组成的数组
    5. some()对数组中的每一项运行给定函数,如果该函数有任一项返回true,则返回true
  9. 归并方法:
    reduce()和reduceRight()这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。

    values.reduce(function(prev,cur,index,array){
        return prev+cur;
    })
    
  10. function类型

    1. 函数声明和函数表达式 函数声明会被解析器优先读取,并使其在执行任何代码之前可用
      函数表达式,必须等到解析器执行到它所在的代码行,才会真正被解释执行

          //函数声明
          function sum(n1,n2){
              return n1+n2
          }
          
          //函数表达式
          var sum = function(n1,n2){
              return n1+n2
          }
      
    2. 函数内部属性:
      arguments和this,还有一个叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

    3. apply()和call()的区别:
      使用call()方法时,传递给函数的参数必须逐个列举出来。

    4. bind()方法:
      这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值

      window.color = "red";
      var o = {color:"blue"};
      
      function sayColor(){
          alert(this.color);
      }
      var objetSayColor = sayColor.bind(o);
      objectSayColor(); //blue
      
    5. 基本包装类型:

      1. number:
        num.toFixed(2),可以表示0-20个小数位的数值
      2. string:
        string.concat("world","!") //world! 拼接字符串 string.slice(p1,p2) //返回新字符串,同array方法 string.indexOf() 如果没有匹配到则返回-1,匹配到,则返回位置 string.trim() 删除前后空格 string.toLowerCase()和string.toUpperCase() 转小写和转大写
      3. Global对象
        encodeURI()和encodeURIComponent() 可以对uri进行编码,过滤特殊字符。 eval("alert('hi')") eval方法,可以用来执行方法
      4. Math对象
        min()和max() 这两个方法都可以接受任意多个数值参数
        Math.ceil()向上取整
        Math.floor()向下取整
        Math.round()四舍五入取整
        Math.random() 产生一个

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

    1. 属性类型

      数据属性

      configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 Enumerable:表示能否通过for-in循环返回属性。 Writable:表示能否修改属性的值。 Value:表示这个属性的数据值。

      访问器属性

      configurable:表示能否通过delete删除属性从而重新定义属性。 enumerable:表示能否通过for-in循环返回属性。 get:在读取属性时调用的函数。 set:在写入属性时调用的函数。

      读取属性的特性

      使用object.getOwnPropertyDescriptor()方法可以取得给定属性的描述符。

    2. 创建对象

      工厂模式

      function createPerson(name,age,job){
           var o = new Object();
           o.name = name;
           o.age = age;
           o.job = job;
           o.sayName = function(){
               alert(this.name);
           }
           return o;
      }
      var person1 = createPerson("Nicholas",29,"Software Engineer");
      

      构造函数模式

      function Person(name,age,job){
          this.name=name;
          this.age=age;
          this.job=job;
          this.sayName=function(){
              alert(this.name);
          }
      }
      var person1=new Person("Nicholas",29,"Softwar Engineer")
      

      和工厂模式的不同:

      1. 没有显示的创建对象
      2. 直接将属性和方法赋给了this对象
      3. 没有return语句

    要创建Person的新实例,必须使用new操作符。这种方式会经历4个步骤

    1. 创建一个新对象
    2. 将构造函数的作用域赋给新对象
    3. 执行构造函数中的代码
    4. 返回新对象
      新对象都有一个constructor属性,该属性指向Person

    构造函数的问题

    1. 每个方法都要在每个实例上重新创建一遍。
    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayName=sayName;
    }
    function sayName(){
        alert(this.name);
    }
    

    以上问题可以通过使用原型模式来解决。

    原型模式

    function Person(){}
    Person.prototype.name="Nicholas";
    Person.prototype.age=29;
    Person.prototype.job="software engineer";
    Person.prototype.sayName=function(){
        alert(this.name);
    }
    var person1=new Person();
    person1.sayName(); //"Nicholas"
    var person2=new Person();
    person2.sayName(); //"Nicholas"
    alert(person1.sayName == person2.sayName); //true
    
    1. 使用hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。
    2. object.keys()方法接受一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。

    原型对象的缺点:

    1. 省略了为构造函数传递初始化参数的环节。
    2. 原型模式的组大问题是由其共享的本性所导致的。

    组合使用构造函数模式和原型模式

    继承

    1. 原型链:
      原型链的问题:
      1. 在通过原型来实现继承时,原型实际上回变成另一个类型的实例。
      2. 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
    2. 借用构造函数:
      借用构造函数的问题:
      1. 方法都在构造函数中定义,函数复用无从谈起
    3. 组合继承:
      指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长。
    4. 原型式继承:
    5. 寄生式继承:
    6. 寄生组合式继承:

第七章 函数表达式

定义函数有两种方式:

  1. 函数声明和函数表达式
    function name(arg0,arg1,arg2){} //函数声明
    
    关于函数声明,一个重要的特征就是函数声明提升,意思是在执行代码之前会先读取函数声明。
    var functionName=function(arg){} //函数表达式
    
  2. 闭包:是指有权访问另一个函数作用域中的变量的函数

第八章 BOM

  1. window对象有双重角色:
    1. 既是通过js访问浏览器窗口的一个接口
    2. 也是global对象
  2. location对象:
    1. hash #hcontents
    2. host www.wrox.com:80 服务器名称和端口号
    3. hostname www.wrox.com 不带端口号的服务器名称
    4. href http:/www.wrox.com 返回完整的url
    5. pathname /wileycdea/ 返回url中的目录和文件名
    6. port 8080 返回端口
    7. protocol http: 返回协议
    8. search ?q=javascript 返回url的查询字符串
  3. 位置操作:
    1. 跳转一个新页面:
      location.assign("www.baidu.com");
      window.location="www.baidu.com";
      location.href="www.baidu.com";
      location.replace="www.baidu.com";//替换现在的url
      location.reload() //重新加载当前页面(可能从缓存中加载)
      location.reload(true) //重新加载(从服务器重新加载)
  4. navigator对象:识别客户端浏览器
  5. screen对象
  6. history对象

第九章 客户端检测

第十章 DOM

第十一章 DOM扩展

  1. querySelector()
  2. querySelectorAll()
  3. HTMLDocument的变化:
    document.readyState //complete 已经加载完文档/loading 正在加载文档

第十二章 DOM2和DOM3

第十三章 事件

  1. 事件冒泡:从最具体的元素向上传播
  2. 事件捕获:从不太具体的到最具体的
  3. DOM0 级事件处理
    var btn = document.getElementById("myBtn");
    btn.onclick=function(){
        alert(this.id); //"myBtn"
    }
    
  4. DOM2 级事件处理程序
    var btn = document.getElementById("myBtn");
    btn.addEventListener("click",function(){
        alert(this.id)
    },false//代表在冒泡阶段触发)
    
    使用addEventLIstener添加的事件处理,只能通过removeEventListener来移除
  5. DOM中的事件对象
    btn.addEventListener("click",function(event){
        event.type //类型
        event.target //事件目标
        event.stopPropagation() //取消事件的进一步捕获或冒泡,前提是bubbles为true
        event.preventDefault() //取消事件的默认行为,前提是cancelable是true
    })
    
  6. 事件委托
    对“事件处理程序过多”问题的解决方案就是 事件委托

第十四章 表单脚本

第十五章 使用Canvas绘图

第十六章 HTML5 脚本编程

第十七章 错误处理与调试

  1. try-catch语句
    try{
        
    }catch(error){
        alert(error.message);
    }finally{
        //一定会执行,即使try和catch中有return语句
    }
    

第十八章 JavaScripth与XML

第十九章 E4X的类型

第二十章 JSON

第二十一行 Ajax 与 Comet

var xhr = new XMLHttpRequest();
xhr.open("get","example.php",false)
xhr.send(null)
// responseText:作为响应主体被返回的文本
// status:响应的Http状态
//statusText:HTTP状态的说明

xhr.timeout=1000 //超时设置为1秒钟
xhr.ontimeout=function(){
    alert("timeout")
}
xhr.onreadystatechange=function(){
    if(xhr.readyState==4){
        //0:未初始化
        //1:启动
        //2:发送
        //3:接收
        //4:表示完成
        //之后可以判断xhr.status>=200
    }
}
xhr.abort()终止ajax

第二十二章 高级技巧

  1. 高级定时器
    使用链式调用setTimeout()
    setTimeout(function(){
        setTimeout(arguments.callee,interval);   
    },interval)
    

第二十三章 离线应用与客户端存储

第二十四章 最佳实践

  1. 可维护性
  2. 可读性
  3. 松散解耦
  4. 最小化语句数