书籍:《PHP、MySQL与JavaScript学习手册》第四版

0x01 探究JavaScript

作用:为网站带来动态功能。

位置:完全在网页浏览器上运行的客户端脚本语言

特点:在HTML使用时,要将JS脚本放在标签 <script></script>之间。

注意:

  • JS可以不使用分号,换行起到了分号的作用

  • <head>段加入脚本的优点:在页面加载时就可以执行;该代码能够被文档中任意依赖它们的脚本立即使用;确保JS能将一些如变位(meta)标记之类的对象写入 <head>段,因为默认写入文档。

  • 在不支持JS的浏览器中,如下使用://表示注释

    1
    2
    3
    <script type="text/javascript"><!-
    (Your JavaScript)
    // --></script>
  • 包含JS文件:

    1
    2
    <script src="script.js"></script> //包含本地脚本
    <script src="http://someserver.com/script.js></script>" //网站第三方脚本

    在JS脚本中,不能有 <script></script>标记。

变量:

  • 命名:

    • 字母、数字、$、_。
    • 开头不能有数字。
    • 区分大小写
    • 没有长度限制
  • 字符串变量:

    1
    2
    3
    4
    newstr = 'hello'
    oldstr = "world"
    newstr=oldstr
    document.write(newstr)
  • 数值型变量:

    1
    2
    count = 66
    temp = 12.3
  • 数组:与PHP数组很像

    1
    2
    3
    4
    5
    6
    7
    toy = ['bat','ball','doll']
    face = [[1,2,3],[4,5,6],[7,8,9]]
    top = ['R','G','Y']
    mid = ['W','R','O']
    bot = ['Y','W','G']
    f = [top,mid,bot]
    document.write(f[1][2]) // O
  • 变量类型:与PHP一样,类型非常松散,随着上下文自动改变。

  • 全局变量:定义在函数之外的变量,无论是否用关键字 var

  • 局部变量:函数数值传参为值,数组传参为引用。局部变量在函数内使用 关键字var

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>
    test()
    if(typeof a != 'undefined') document.write(a)
    if(typeof b != 'undefined') document.write(b)
    if(typeof c != 'undefined') document.write(c)

    function test()
    {
    a = 123
    var b = 456
    if(a == 123) var c = 789
    }

    结果:

    1
    123

运算符:

  • 算数运算符、赋值运算符、比较运算符与PHP相同。

  • 比较运算符也包括 类型比较===!==

  • 逻辑运算符:&&||!

  • 自增自减

  • 字符串连接: + 解释:.被用来分离对象、属性和方法。

  • 转义字符:\

    字符 含义
    \b 退格
    \f 换页
    \n 换行
    \r 回车
    \t 制表
    \’ 单引号
    \" 双引号
    \\ 反斜杠
    \XXX 000-377之间的八进制数,代表Latin-1字符
    \xXX 00-FF之间的十六进制数,代表Latin-1字符
    \uXXXX 0000-FF之间的十六进制数,代表Unicode字符

函数:

1
2
3
4
function product(a,b)
{
return a*b
}

文档对象模型(DOM):

​ DOM树:

  • 链接:

    1
    2
    3
    4
    url = document.links[0].href
    numlinks = document.links.length
    for (j = 0;j<document.links.length;++j)
    document.write(document.links[j].href+'<br>')
  • 浏览记录:

    1
    2
    3
    4
    5
    document.write(history.length)
    history.go(-3) //回退三页
    history.back() //回退一页
    history.forward() //前进一页
    document.location.href = 'http://google.com'//代替当前加载的URL

关于document.write:

  • 简单快速显示结果
  • 可以将内容写入HTML
  • 但是不安全:网页全部加载后,对其调用会覆盖当前文档。因此不推荐使用,此处知识我我了教学方便。
  • 替换方案:console.logalert

0x02 表达式与控制流

​ 与PHP极为相似,但也有部分不同。

  • JS布尔表达式结果是 truefalse(小写);PHP结果是1NULL

  • 运算符:优先级从高到低

    运算符 类型
    () [] . 括号、调用、成员
    ++ – 自增/自减
    + - ~ ! 一元、按位、逻辑
    * / % 算术
    + - 算术和字符串
    << 、>>、 >>> 按位
    <、>、<=、>= 比较
    ==、!=、===、!== 比较
    & ^ | 按位
    && 逻辑与
    || 逻辑或
    ?: 三元
    =、+=、-=、<<=、>>>=、&= 赋值
    顺序
  • ==等值运算符,===恒等运算符(禁止类型转换)

  • with语句:

1
2
3
4
5
6
7
<script>
str = "lowbee"
with(str){
document.write(length+'<br>')
document.write(toUpperCase())
}
</script>

运行结果:

原因:JavaScript编译器能检测到lengthtoUpperCase()方法必须被应用到某个对象上。因为这两个语句是独立的,编译器会把他们看作是与 with语句指定的 string对象相关的。

  • onerror:捕获语法错误

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>
    onerror = errorHandler //自定义错误处理函数
    document.writ("hello lowbee") //错误地点
    function errorHandler(message,url,line){
    out = "Sorry,an error was encountered.\n"
    out += "Error:"+message+"\n"
    out += "line:"+line+"\n"
    out +="Click OK to continue.\n"
    alert(out)
    return true
    }
    </script>

    结果:

  • try...catch...(finally):捕获选定区域的异常。

  • 条件语句:

    • if...(else)
    • switch..casedefault
    • ? :
  • 循环:

    • while
    • do...while
    • for
  • 跳出:

    • break
    • continue
  • 显示类型转换:

    转换类型 使用函数
    int,integer parseInt()
    Bool,Boolean Boolean()
    Float,double,real parseFloat()
    String String()
    Array split()

0x03 函数、对象、数组

函数:

  • 定义函数:

    1
    2
    3
    4
    function function_name([parameter[,...]])
    {
    statements
    }
    • 函数名由字母或下划线开头,书上没提$,但是实测可以

    • 大小写敏感,推荐驼峰命名,例如:getInput()

    • 参数数组:将参数作为数组传入

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      <script>
      displayItems("dog","cat","pony","lowbee","bob")
      // function displayItems(v1,v2,v3,v4,v5)
      // {
      // document.write(v1+'<br>')
      // document.write(v2+'<br>')
      // document.write(v3+'<br>')
      // document.write(v4+'<br>')
      // document.write(v5+'<br>')
      // }
      function displayItems()
      {
      for (j =0;j<displayItems.arguments.length;j++)
      {
      document.write(displayItems.arguments[j]+'<br>')
      }
      }
      </script>
  • 返回值

    • 普通元素
    • 数组

对象:

  • 声明:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <script>
    function User(name,age)
    {
    this.name = name //共有变量
    var age = age //私有变量

    this.showName = function() //共有方法
    {
    document.write("Name is "+this.name+"<br>")
    }
    var showAge = function() //私有方法
    {
    document.write("Age is "+age+'<br>')
    }
    }
    lowbee = new User("lowbee",66)
    lowbee.showName()
    lowbee.showAge()//类外无法使用
    </script>

    运行结果:

    分别定义类和方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <script>
    function User(name)
    {
    this.name = name
    this.showName = showName
    }
    function showName()
    {
    document.write("Name is "+this.name+"<br>")
    this.showAge()
    }

    lowbee = new User("lowbee")
    lowbee.showName()

    </script>
  • prototype关键字

    ​ 如果有1000个User对象,那么 showName()就会重复1000次,浪费资源。prototype就是解决这问题的,包括属性和方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <script>
    function User(name,age)
    {
    this.name = name //共有变量
    var age = age //私有变量

    User.prototype.showName = function() //共有方法
    {
    document.write("Name is "+this.name+"<br>")
    }
    var showAge = function() //私有方法
    {
    document.write("Age is "+age+'<br>')
    }
    }
    lowbee = new User("lowbee",66)
    lowbee.showName()
    lowbee.showAge()//类外无法使用
    </script>

    可以在任何时候添加和 prototype属性和方法,所有对象都可以继承。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //添加属性
    bob = new User()
    User.prototype.greeting = "Hello"
    document.write(bob.greeting)

    //修改方法
    User.prototype.showName = function()
    {
    document.write("My Name is "+this.name+'<br>')
    }

数组:

  • 数值数组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <script>
    a = new Array() // a =[]
    a[0] = "One"
    a.push("Two")
    // a = Array("One","Two")
    for (j=0;j<a.length;++j)
    {
    document.write(a[j]+"<br>")
    }
    </script>
  • 关联数组:

    ​ 还是字典。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <script>
    a ={
    "1":"One",
    "2":"Two"
    }
    for (num in a)
    {
    document.write(num +" is "+a[num]+"<br>")
    }
    </script>
  • 多维数组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <script>
    checker = Array(
    Array(" ","o"," ","o"," ","o"," "),
    Array(" "," "," "," "," ","o"," "),
    Array(" ","o"," ","o"," ","o","o"),
    Array(" ","o"," ","o"," "," "," "),
    Array(" ","o"," "," "," ","o","o"),
    Array(" "," "," ","o"," "," ","o")
    )
    document.write('<pre>')

    for(i = 0;i<checker.length;i++)
    {
    for(j = 0;j<checker[i].length;j++)
    document.write(checker[i][j]+" ")

    document.write("<br>")

    }
    document.write('<pre>')
    </script>

    结果:

    1
    2
    3
    4
    5
    6
    o   o   o   
    o
    o o o o
    o o
    o o o
    o o
  • 使用方法:

    • concat():拼接数组

      1
      2
      3
      4
      5
      6
      <script>
      pets = ["Cat","Dog","Fish"]
      more_pets = pets.concat("Hamster")
      document.write(more_pets+'<br>')
      document.write(more_pets.concat(pets))
      </script>
      1
      2
      Cat,Dog,Fish,Hamster
      Cat,Dog,Fish,Hamster,Cat,Dog,Fish
    • forEach():遍历(非IE浏览器)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <script>
      pets = ["Cat","Dog","Fish"]
      more_pets = pets.concat("Hamster")
      more_pets.forEach(output)
      function output(element,index,array)
      {
      document.write(index +" is "+element+"<br>")
      }
      </script>

      结果:

      1
      2
      3
      4
      0 is Cat
      1 is Dog
      2 is Fish
      3 is Hamster
    • join():将所有值转化成字符串,并按照连接符拼成一个大的字符串。默认连接符是

      1
      2
      3
      4
      5
      6
      7
      <script>
      pets = ["Cat","Dog","Fish"]
      more_pets = pets.concat("Hamster")
      document.write(more_pets.join()+"<br>")
      document.write(more_pets.join(" ")+"<br>")
      document.write(more_pets.join(":")+"<br>")
      </script>

      结果:

      1
      2
      3
      Cat,Dog,Fish,Hamster
      Cat Dog Fish Hamster
      Cat:Dog:Fish:Hamster
    • push()pop():将数组看成栈,后进先出

      1
      2
      myArray.push("aaa")
      b = myArray.pop() //b ="aaa"
    • reverse(): myArray.reverse()逆序。

    • sort():

      1
      2
      3
      4
      5
      6
      7
      8
      <script>
      pets = ["Cat","Dog","Fish","Hamster"]
      document.write(pets.sort()+"<br>")
      document.write(pets.sort().reverse()+"<br>")
      num = [4,5,6,1,2,3,1]
      document.write(num.sort(function(a,b){return a-b})+"<br>")
      document.write(num.sort(function(a,b){return b-a})+"<br>")
      </script>

      结果:

      1
      2
      3
      4
      Cat,Dog,Fish,Hamster
      Hamster,Fish,Dog,Cat
      1,1,2,3,4,5,6
      6,5,4,3,2,1,1

0x04 JS和PHP验证与错误处理

​ 来任务了。。

0x05 Ajax