JS学习笔记

JS的编写的位置:
  1.可以编写到标签的指定属性中
     <button onclick="alert('hello');">我是按钮</button>  
     <a href="javascript:alert('aaa');">超链接</a>
  2.可以编写到script标签中
     <script type="text/javascript">  
     //编写js代码  
     </script>
  3. 可以将代码编写到外部的js文件中,然后通过标签将其引入
       script标签一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略 ,如果需要则可 
       以在创建一个新的script标签用于编写内部代码
       <script type="text/javascript" src="文件路径"></script>

-----------------------------------------------------------------------------------------
基本的语法:
   单行注释://注释内容
   多行注释: /*  
            注释内容  
            */
   JS严格区分大小写
   JS中每条语句以分号(;)结尾
     如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,
     而且有些时候,浏览器会加错分号,所以在开发中分号尽量写
   JS中会自动忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化。

-----------------------------------------------------------------------------------------
字面量:
  都是一些不可改变的值,比如1,2,3,4,5
  字面量都是可以直接使用,但是一般不会直接使用
变量:
  变量可以用来保存字面量,而且变量的值是可以任意改变的
  变量更加方便使用,所有开发中都是通过变量去保存一个字面量而很少直接用字面量
  可以通过变量对字面量进行描述
声明变量并赋值
  使用var关键字来声明一个变量 var a=1

-----------------------------------------------------------------------------------------
标识符:
  在JS中所有的可以自主命名的内容,都可以认为是一个标识符,
  例如:变量名、函数名、属性名
  规则:
    1.标识符中可以含有字母、数字、_、$
    2.标识符不能以数字开头
    3.标识符不能是ES中的关键字和保留字
    4.标识符一般采用驼峰命名法,首字母小写,每个单词开头字母大写,其余字母小写,例如:xxxYyyZzz
  JS底层保存标识符时实际上是采用的Unicode编码,所以理论上所有的uft-8中的内容都可以作为标识符

-----------------------------------------------------------------------------------------
数据类型:
  JS中一共分成六种数据类型 ,5个基本数据类型和一个引用数据类型object
  String字符串
    在js中字符串需要有双引号或单引号引起了
    例:var str="hello"
    在字符串中使用\作为转义字符 \'==>'  \"==>"  \n==>换行  \t==>制表符  \\==>\
    使用typeof运算符检查字符串时,会返回”string”
  Number数值
    JS中所有的整数和浮点数都是Number类型
    最大能表示的值:Number.MAX_VALUE= 1.7976931348623157e+308
    大于零的最小值:Number.MIN_VALUE=5e-324
    Infinity正无穷 
    -Infinity 负无穷
    NaN 一个特殊的数字(Not A Number)
    使用typeof检查一个Number类型的数据时,会返回"number"(包括NaN 和 Infinity)
    如果用js进行浮点数运算,可能得到一个不精确的结果
    其他进制的数字:
      如果需要表示16进制的数字,则需要以0x开头
      如果需要表示8进制的数字,则需要以0开头
      如果需要表示2进制 的数字,则需要以0b开头,但不是所有的浏览器都支持
        如想解析字符串为数字,"070",有些浏览器会当成8进制解析,有些则会当成10进制解析,
        我们在使用parseInt()中传递一个第二参数,来指定进制 
        var a =070   a =paseInt(a,10);//指定为10进制
  Boolean 布尔值:
    布尔值主要用来进行逻辑判断,布尔值只有两个
    true 逻辑的真
    false 逻辑的假
    使用typeof检查一个布尔值时,会返回"boolean"
  Null 空值
    空值专门用来表示为空的对象,Null类型的值只有一个null
    使用typeof检查一个Null类型的值时会返回"object"
  Undefined 未定义
    如果声明一个变量但是没有为变量赋值此时变量的值就是undefined
    该类型的值只有一个 undefined
    使用typeof检查一个Undefined类型的值时,会返回"undefined"
  引用数据类型
    Object 对象

-----------------------------------------------------------------------------------------
类型转换:
  类型转换就是指将其他的数据类型
  转换为String:
    方式一:调用被转换数据的toString()方法(强制类型转换)
       例子:
           var a = 123;    a = a.toString();
       注意:这个方法不适用于null和undefined,
            由于这两个类型的数据中没有toString方法,所以调用toString()时会报错
    方式二:调用String()函数(强制类型转换)
       使用String()函数对于Number Boolean 实际上就是调用他们的toString()方法,
       但对于null值,是直接转换为字符串”null”。对于undefined直接转换为字符串”undefined”
  转换为Number:
    方式一:使用Number()函数(强制类型转换)
           var s = "123";  s = Number(s);
           转换的情况:
             字符串 > 数字:
                  如果字符串是一个合法的数字,则直接转换为对应的数字
                  如果字符串是一个非法的数字,则转换为NaN
                  如果是一个空串或纯空格的字符串,则转换为0
             布尔值 > 数字:
                  true转换为1
                  false转换为0
             空值 > 数字
                  null转换为0
             未定义 > 数字
                  undefined 转换为NaN
    方式二:调用parseInt()或parseFloat()(强制类型转换)
           这两个函数专门用来将一个字符串转换为数字的,
           如果对非字符串使用parseInt()或parseFloat(),它会先将其转变为String类型,再操作
           parseInt(参数) 把一个字符串转换为一个整型数
           parseFloat(参数) 把一个字符串转换为一个浮点数
   转换成Boolean:
     使用Boolean()函数 
       数字==>布尔  除了0和NaN,其余都是true
       字符串==>布尔 除了空串,其余的都是true
       null和undefined都会转换false
       对象也会转换为true

-----------------------------------------------------------------------------------------
算数运算符:
  当对非Number类型的值进行运算时,会将这些值转换Number然后在运算(字符串除外)
  任何值和NaN做运算都得NaN
  +:
    +可以对两个值进行加法运算
    如果对两个字符串进行加法运算,则会进行拼串处理
    任何的值和字符串做加法,都会先转换为字符串,然后再和字符串做拼串操作
  -:
    -可以对两个值进行减法运算
  *:
    *可以对两个值进行乘法运算
  /:
    /可以对两个值进行除法运算
  %:
    %可以取模运算(取余数)
  注意:
     (1)任何值做- * / 运算时都会自动转换为Number
        我们可以利用这个特性做隐式的类型转换
    ​    可以通过为一个值 - 0 *1 /1来将其转换为Number
        原理和Number()函数一样,使用起来更简单
     (2)任何的值和字符串做加法都会先转换为字符串,然后并做拼串操作
        可以利用这一特点来将任意数据类型转为string
        可以通过数字+""来将其转换为字符串,原理也和String()函数一样
    
-----------------------------------------------------------------------------------------
一元运算符:
   一元运算符:只需要一个操作数
   +正号:
        不会对数字产生任何影响
   -负号:
        负号可以对数字进行符号的取反
   注意:
       对于非Number类型的值,它会将类型先转换为Number,然后在进行运算
       可以对一个其他的数据类型使用+,来将其转换为Number​,它的原理和Number()函数一样

-----------------------------------------------------------------------------------------
自增与自减运算符:
   自增++:
         自增可以使变量在原值的基础上自增1
         自增分为两种,前++(++a),后++(a++)
         无论是++a还是a++都会立即使原变量自增1
         不同的是++a和a++的值不同:
           ++a的值是变量的新值(自增后的值)
           a++的值是变量的原值(自增前的值)
   自减--:
         自减可以使变量在原值的基础上自减1
         自减分为两种,前--(--a),后--(a--)
         无论是--a 还是a--都会立即使原变量自减1
         不同的是–a和a–的值不同:
           --a的值是变量的新值(自减后的值)
           a--的值是变量的原值(自减前的值)

-----------------------------------------------------------------------------------------
逻辑运算符:
  JS中为我们提供了三种逻辑运算符
  ! 非: 
       ! 可以用来对一个值进行非运算
       所谓非运算就是值对一个布尔值进行取反操作
         true便false false 便true
       如果对一个值进行两次取反,它将不会发生变化
       如果对非布尔类型的元素进行取非,它将会转换为布尔值在取反
         所以我们可以利用该特点,来将一个其他的数据类型转变为布尔类型
         可以为一个任意数据类型取反两次,来将其转换为布尔值
         原理和Boolean()函数一样
  && 与:
        &&可以对符号两侧的值进行与运算并返回结果
        运算规则:
           两个值中只要有一个值为false就返回false
           只有两个值都为true时,才会返回true
        JS中的"与"属于短路与
           如果第一个值为false,则不会去看第二个值
  || 或:
        || 可以对符号两侧的值进行或运算并返回结果
        运算规则:
          两个值只要有一个true,就返回true
            如果两个值都为false,才会返回false
          JS中的"或"属于短路的或
            如果第一个值为true,则不会检查第二个值

-----------------------------------------------------------------------------------------
&& || 非布尔判断的情况:
  对于非布尔值进行与或运算时,会对其转换为布尔值,然后在运算,并且返回原值
  与运算:
      如果第一个值时true,则必然返回第二个值
      如果第一个值时false,则之间返回第一个值
  或运算
      如果第一个值是true,直接返回第一个值
      如果第一个值是false,则返回第二个值

-----------------------------------------------------------------------------------------
赋值运算符:
   =: 可以将符号右侧的值赋值给符号左侧的变量
  +=: a+=5等价于a=a+5
  -=:  a-=5等价于a=a-5
  *=: a*=5等价于a=a*5
  /=:  a/=5等价于a=a/5
  %=:  a%=5等价于a=a%5

-----------------------------------------------------------------------------------------
Unicode编码:
  在字符串中使用转义字符输入Unicode编码:\u四位编码
   console.log("\u1c00") 
  在网页中使用Unicode编码:
   用"&#"编码,这里的编码需要的是10进制
   <h1>"&#"9760</h1>(这里不需要用双引号,不用双引号代码没有高亮)
   
-----------------------------------------------------------------------------------------
比较运算符(关系运算符)
  >  <  >=  <=
  通过关系运算符可以比较两个值之间的大小关系,如果关系成立返回true,如果不成立返回false
  非数值的情况:
    对于非数值进行比较时,会将其转换为数字然后再比较
    如果符号两侧都是字符串是,不会将其转换为数字进行比较,而是会分别比较字符串中字符的Unicode编 
    码,一个字符一个字符的比

-----------------------------------------------------------------------------------------
相等运算符:
  想等运算符用来比较两个值是否相等,如果相等会返回true,否则返回false
  相等==:
    使用==来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型,然后再比较
  不相等!=:
     不相等用来判断两个值是否不相等,如果不相等返回true,否则返回false
     使用!=来做不相等运算:
       不相等也会对变量进行自动类型转换,如果转换后相等,则返回false,不相等则返回true
  全等===:
     用来判断两个值是否相等,它和相等类似,不同的是它不会做自动类型转换,如果两个值的类型不同直接返回false
  不全等!==:
     用来判断两个值是否不全等 ,和不等类型,不同的是它也不会自动转换类型。如果两个值的类型不同,直接 返回true
  拓展:
     NaN不和任何值相等,包括他本身
     undefined衍生自null,所以这两个值做相等判断时,会返回true,所以我们在做变量值是否为NaN时,不能用==而是用isNaN()函数
     尽量不要用==来做判断,类型不一样,值一样也会返回true

-----------------------------------------------------------------------------------------
三元运算符:
  语法:​ 条件表达式?语句1:语句2;
  执行的流程:
     条件运算符在执行时,首先对条件表达式进行求值
        如果该值为true,则执行语句1,并返回执行结果
        如果该值为false,则执行语句2,并返回执行结果
     如果条件的表达式的求值结果是一个非布尔值,会将其转换为布尔值然后再运算

-----------------------------------------------------------------------------------------
运算符优先级:
   不需要背
   如果遇到优先级不清楚的可以用()改变优先级

-----------------------------------------------------------------------------------------
代码块:
  我们的程序由一条条语句构成的,语句是按照自上而下的顺序一条条执行。
  在JS中可以使用{}来为语句进行分组,同一个{}的语句称为一组语句,它们要么都执行,要么都不执行。
  一个{}中的语句,我们称为一个代码块,在代码块后,不需要写;了。
  JS的代码块,只具有分组作用,没有其他用途

-----------------------------------------------------------------------------------------
流程控制语句:
   1. (条件判断语句)if语句: 
        if(条件表达式){  
	        语句...  
        }else if(条件表达式){  
	        语句...  
        }else if(条件表达式){  
            语句...  
        }else{
            语句...  
        }
        执行流程:
          if...else if...else语句执行时,会自上至下依次对条件表达式进行求值判断,  
	      如果判断结果为true,则执行当前if后的语句,执行完成后语句结束。  
	      如果判断结果为false,则继续向下判断,直到找到为true的为止。  
	      如果所有的条件表达式都是false,则执行else后的语句
   2. (条件分支语句)switch语句:
        switch(条件表达式){  
	       case 表达式:  
	       	  语句...  
		       break;  
     	   case 表达式:  
		       语句...  
		       break;  
	       default:  
		       语句...  
         }
         执行流程:
          switch…case…语句在执行时,会依次将case后的表达式的值和switch后的表达式的值进行全等比较
          如果比较结果为false,则继续向下比较
          如果比较结果为true,则从当前case处开始向下执行代码
          如果所有的case判断结果都为false,则从default处开始执行代码。
    3. 循环语句
       (1)while循环:
         while(条件表达式){  
             语句...  
         }
          执行流程:
            while语句在执行时,会先对条件表达式进行求值判断,
            如果判断结果为false,则终止循环
            如果判断结果为true,则执行循环体
            循环体执行完毕,继续对条件表达式进行求值判断,依此类推
       (2)do...while循环:
          do{  
             语句...  
          }while(条件表达式)
          执行流程:
            do…while在执行时,会先执行do后的循环体,然后在对条件表达式进行判断,
            如果判断判断结果为false,则终止循环。
            如果判断结果为true,则继续执行循环体,依此类推
          和while的区别:
            while:先判断后执行
            do…while: 先执行后判断
            do…while可以确保循环体至少执行一次。
       (3)for循环;
          for(①初始化表达式 ; ②条件表达式 ; ④更新表达式){  
                ③语句...  
          }
          执行流程:
            首先执行①初始化表达式,初始化一个变量,
            然后对②条件表达式进行求值判断,如果为false则终止循环
            如果判断结果为true,则执行③循环体
            循环体执行完毕,执行④更新表达式,对变量进行更新。
            更新表达式执行完毕重复②

-----------------------------------------------------------------------------------------
break关键字和continue
  break用来退出switch或循环语句
  不能再if语句中用break和continue 
  break会立即终止离他最近的循环语句
  可以为循环语句创建一个lable来标识当前循环:label:循环语句
  使用break语句时,可以在break后跟一个lable,这样break将结束指定的循环而不是最近的
  continue用来跳过当初循环,也是只会对离他最近的循环起作用

-----------------------------------------------------------------------------------------
console.time("计时器名字")可以用来开启一个计时器,需要一个字符串做参数,字符串将作为计时器的标识
console.timeEnd("计时器名字")可以停止一个计时器,需要一个计时器名字做参数

-----------------------------------------------------------------------------------------
对象:
  对象是JS中的引用数据类型
  对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性
  使用typeof检查一个对象时,会返回object
  创建对象
		- 方式一:
			- var obj = new Object();
		- 方式二:
			- var obj = {};

-----------------------------------------------------------------------------------------向对象中添加属性
  语法:
	  对象.属性名 = 属性值;
	  对象["属性名"] = 属性值;
	  对象的属性名没有任何要求,不需要遵守标识符的规范,但是在开发中,尽量按照标识符的要求去写。
	  属性值也可以任意的数据类型。
读取对象中的属性
	语法:
		对象.属性名
		对象["属性名"]
		如果读取一个对象中没有的属性,它不会报错,而是返回一个undefined
删除对象中的属性
	语法:
		delete 对象.属性名
		delete 对象["属性名"]
使用in检查对象中是否含有指定属性
	语法:"属性名" in 对象
		  如果在对象中含有该属性,则返回true
		  如果没有则返回false

-----------------------------------------------------------------------------------------
使用对象字面量,在创建对象时直接向对象中添加属性
		语法:
			var obj = {
							属性名:属性值,
							属性名:属性值,
							属性名:属性值,
							属性名:属性值
					}

-----------------------------------------------------------------------------------------
基本数据类型和引用数据类型
   基本数据类型
	  String Number Boolean Null Undefined
   引用数据类型
	  Object
   基本数据类型的数据,变量是直接保存的它的值。
	  变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
   引用数据类型的数据,变量是保存的对象的引用(内存地址)。
	  如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
   比较两个变量时,对于基本数据类型,比较的就是值,
	  对于引用数据类型比较的是地址,地址相同才相同
			
-----------------------------------------------------------------------------------------
函数(Function)	
   函数也是一个对象,也具有普通对象的功能
   函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码
   使用typeof检查一个函数时会返回function
   创建函数
	   函数声明
		  function 函数名([形参1,形参2...形参N]){
			  语句...
		  }
	   函数表达式
		  var 函数名 = function([形参1,形参2...形参N]){
			  语句...
		  };
   调用函数
	   语法:函数对象([实参1,实参2...实参N]);
		    fun() sum() alert() Number() parseInt()
		    当我们调用函数时,函数中封装的代码会按照编写的顺序执行
   形参和实参
	    形参:形式参数
			 定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开
			 定义形参就相当于在函数内声明了对应的变量但是并不赋值,
			 形参会在调用时才赋值。
		实参:实际参数
			 调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
			 调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
			 如果实参的数量大于形参,多余实参将不会赋值,
			 如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined

-----------------------------------------------------------------------------------------
函数返回值:
	返回值,就是函数执行的结果。
	使用return 来设置函数的返回值。
	语法:return 值;
		- 该值就会成为函数的返回值,可以通过一个变量来接收返回值
	return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
	return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。
	如果return后不跟值,或者是不写return则函数默认返回undefined。

-----------------------------------------------------------------------------------------
立即执行函数:
  语法:
     (function(){
         语句...
     })()
  函数执行完立即被调用,这种函数叫立即执行函数
  立即执行函数只会执行一次
    
-----------------------------------------------------------------------------------------
方法(method)
	可以将一个函数设置为一个对象的属性,
	当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。

-----------------------------------------------------------------------------------------
枚举对象中的属性:
  使用for...in语句
  语法:
      for(var 变量 in 对象){
        console.log(变量)
        console.log(对象[变量])
      }
      for...in语句对象中有几个属性,循环体就执行几次
      每次执行时会将对象中的一个属性的名字赋值给变量

-----------------------------------------------------------------------------------------
作用域:
  作用域简单来说就是一个变量的作用范围。
  在JS中作用域分成两种:
    1.全局作用域
	    直接在script标签中编写的代码都运行在全局作用域中
		全局作用域在打开页面时创建,在页面关闭时销毁。
		全局作用域中有一个全局对象window,window对象由浏览器提供,
            可以在页面中直接使用,它代表的是整个的浏览器的窗口。
		全局作用域中创建的变量都会作为window对象的属性保存
			在全局作用域中创建的函数都会作为window对象的方法保存
		在全局作用域中创建的变量和函数可以在页面的任意位置访问。
		    在函数作用域中也可以访问到全局作用域的变量。
	2.函数作用域
		函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。
		函数作用域在函数执行时创建,在函数执行结束时销毁。
        每调用一次函数就会创建一个新的作用域,他们之间是相互独立的
		在函数作用域中创建的变量,不能在全局中访问。
		当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,
		    如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,
		    如果找到了则使用,找不到则继续向上找,都找不到则报错

-----------------------------------------------------------------------------------------
变量的声明提前:
    在全局作用域中,使用var关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。
	所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。
	在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明,
	如果没有使用var关键字声明变量,则变量会变成全局变量
函数的声明提前:
	在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建,
    也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性
	在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。

-----------------------------------------------------------------------------------------
this(上下文对象):	
     我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。
	 使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。
	 this的不同的情况:
		1.以函数的形式调用时,this是window
		2.以方法的形式调用时,this就是调用方法的对象
		3.以构造函数的形式调用时,this就是新创建的对象
        4.使用call和apply调用时,this是指定的那个对象
        5.在全局作用域中this代表window

-----------------------------------------------------------------------------------------
工厂模式创建对象:
  通过该方法可以大批量创建对象
  function createPerson(name,age){
      var obj=new Object()
      obj.name=name
      obj.age=age
      return obj
  }
  var per=createPerson("xxx","xxx")

-----------------------------------------------------------------------------------------构造函数:
   构造函数是专门用来创建对象的函数
   一个构造函数我们也可以称为一个类
   通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例
   通过同一个构造函数创建的对象,我们称为一类对象
   构造函数就是一个普通的函数,只是他的调用方式不同,
   如果直接调用,它就是一个普通函数
   如果使用new来调用,则它就是一个构造函数
例子:
	function Person(xxx,yyy){
	    this.xxx=xxx
        this.yyy=yyy
	}
    var per=new Person("xxx","yyy")
构造函数的执行流程:
   1.创建一个新的对象
   2.将新的对象作为函数的this
   3.执行函数中的代码
   4.将新建的对象返回
instanceof 用来检查一个对象是否是一个类的实例
   语法:对象 instanceof 构造函数
   如果该对象时构造函数的实例,则返回true,否则返回false
   Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true
		 
-----------------------------------------------------------------------------------------
原型(prototype)
	创建一个函数以后,解析器都会默认在函数中添加一个数prototype
	   prototype属性指向的是一个对象,这个对象我们称为原型对象。
	当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。
	   这个隐含的属性可以通过对象.__proto__来访问。
	原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。
	   我们可以将对象中共有的属性和方法统一添加到原型对象中,
	   这样我们只需要添加一次,就可以使所有的对象都可以使用。
	当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,
	   如果在自身中找到了,则直接使用。
	   如果没有找到,则去原型对象中寻找,如果找到了则使用,
	   如果没有找到,则去原型的原型中寻找,依此类推 。直到找到Object的原型为止,Object的原型的原型为null,
	   如果依然没有找到则返回undefined
hasOwnProperty()
	这个方法可以用来检查对象自身中是否含有某个属性
	语法:对象.hasOwnProperty("属性名")
		
-----------------------------------------------------------------------------------------
垃圾回收(GC):
  就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
     这些垃圾积攒过多以后,会导致程序运行的速度过慢,
     所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
  当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
     此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
     所以这种垃圾必须进行清理。
  在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
     我们不需要也不能进行垃圾回收的操作
     我们需要做的只是要将不再使用的对象设置null即可

-----------------------------------------------------------------------------------------
数组(Array)
    数组也是一个对象,是一个用来存储数据的对象
	和Object类似,但是它的存储效率比普通对象要高
	数组中保存的内容我们称为元素	
	数组使用索引(index)来操作元素
	索引指由0开始的整数
    数组中的元素可以是任何数据类型
    判断是否是数组:Array.isArray()
	数组的操作:
	   创建数组:
			var arr = new Array(); 创建一个空数组
            var arr=new Array(2); 表示数组长度为2,里面有两个空的数组元素
            var arr=new Array(2,3); 等价于[2,3],表示里面有两个数组元素
			var arr= [];创建一个空数组
	   向数组中添加元素:
			语法;
				数组对象[索引] = 值;
	   创建数组时直接添加元素
			语法:
				var arr = [元素1,元素2....元素N];	
	   获取和修改数组的长度
			使用length属性来操作数组的长度
			获取长度:
			   数组.length
			   length获取到的是数组的最大索引+1
			   对于连续的数组,length获取到的就是数组中元素的个数
			修改数组的长度
			   数组.length = 新长度
			   如果修改后的length大于原长度,则多出的部分会空出来
			   如果修改后的length小于原长度,则原数组中多出的元素会被删除
			向数组的最后添加元素
			   数组[数组.length] = 值;
 	
-----------------------------------------------------------------------------------------
数组的方法:
   push()
		用来向数组的末尾添加一个或多个元素,并返回数组新的长度,会改变原数组
		语法:数组.push(元素1,元素2,元素N)
   pop()
		用来删除数组的最后一个元素,并返回被删除的元素,会改变原数组
   unshift()
		向数组的前边添加一个或多个元素,并返回数组的新的长度,会改变原数组
   shift()
		删除数组的第一个元素,并返回被删除的元素,会改变原数组
   slice()
		可以从一个数组中截取指定的元素
		该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回
		参数:
			1.截取开始位置的索引(包括开始位置)
			2.截取结束位置的索引(不包括结束位置)
			第二个参数可以省略不写,如果不写则一直截取到最后
			参数可以传递一个负值,如果是负值,则从后往前数
   splice()
		可以用来删除数组中指定元素,并使用新的元素替换,会改变原数组
		该方法会将删除的元素封装到新数组中返回
		参数:
			1.删除开始位置的索引
			2.删除的个数
			3.三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边
   reverse()
		可以用来反转一个数组,它会对原数组产生影响
   concat()
		可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回
   join()
		可以将一个数组转换为一个字符串,不会对原数组产生影响,而是将转换的字符串作为结果返回
		参数:
			需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素
			如果不指定连接符则默认使用,
   sort()
		可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序
		调用以后,会直接修改原数组。
		可以自己指定排序的规则,需要一个回调函数作为参数:
			function(a,b){
				return a-b;//升序排列
				return b-a;//降序排列
			}		

-----------------------------------------------------------------------------------------
遍历数组:
    使用forEach()方法来遍历数组(不兼容IE8)
	数组.forEach(function(value , index , obj){
	});	
	forEach()方法需要一个回调函数作为参数,
	数组中有几个元素,回调函数就会被调用几次,
	每次调用时,都会将遍历到的信息以实参的形式传递进来,
	我们可以定义形参来获取这些信息。
	value:正在遍历的元素
	index:正在遍历元素的索引
	obj:被遍历数组

-----------------------------------------------------------------------------------------
call()和apply():
    这两个方法都是函数对象的方法,需要通过函数对象来调用
    当函数调用call()和apply()时都会调用函数执行
    调用call()和apply()可以将一个对象指定为第一个参数
    此时这个对象就是函数执行时的this
    区别:
       call()方法可以将实参在对象后依次传递
       apply()需要将实参封装到一个数组中统一传递
bind():
    该方法也是函数对象的方法,需要通过函数对象来调用
    当函数调用bind()时不会调用函数执行
    可以改变函数内部的this指向
    返回值是原函数改变this之后产生的新函数
-----------------------------------------------------------------------------------------
arguments:
	arguments和this类似,都是函数中的隐含的参数
    在调用函数时,我们所传递的实参都在arguments中保存
    arguments.length可以获取实参长度
    arguments是一个类数组元素,它用来封装函数执行过程中的实参
    所以即使不定义形参,也可以通过arguments来使用实参
	arguments中有一个属性callee表示当前执行的函数对象

-----------------------------------------------------------------------------------------
Date对象:
  在JS中使用Date对象来表示一个时间
  创建一个当前的时间对象:
    var d = new Date();
  方法:
       getDate()	当前日期对象是几日(1-31)
       getDay()	  返回当前日期对象时周几(0-6)0 周日 1 周一 。。。
       getMonth()	返回当前日期对象的月份(0-11)0 一月 1 二月 。。。
       getFullYear()	从 Date 对象以四位数字返回年份。
       getHours()	返回 Date 对象的小时 (0 ~ 23)。
       getMinutes()	返回 Date 对象的分钟 (0 ~ 59)。
       getSeconds()	返回 Date 对象的秒数 (0 ~ 59)。
       getMilliseconds()	返回 Date 对象的毫秒(0 ~ 999)。
       setHours()	设置 Date 对象中的小时 (0 ~ 23)
       Date.now()	可以获取当前代码执行时的时间戳
       getTime()	返回当前日期对象的时间戳
                    时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数
                    计算机底层保存时间都是以时间戳的形式保存的。
      
-----------------------------------------------------------------------------------------
Math:
   Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法
   我们可以直接使用它来进行数学运算相关的操作
   方法:
       Math.PI 常量,圆周率
       Math.abs()   绝对值运算
       Math.ceil()  向上取整
       Math.floor()  向下取整
       Math.round()  四舍五入取整
       Math.random()  生成一个01之间的随机数
       Math.round(Math.random()*(y-x)+x)  生成一个xy之间的随机数
       Math.pow(x,y)  求x的y次幂
       Math.sqrt()  对一个数进行开方
       Math.max()  求多个数中最大值
       Math.min()  求多个数中的最小值

-----------------------------------------------------------------------------------------
包装类:		
	在JS中为我们提供了三个包装类:
	   String() Boolean() Number()
	通过这三个包装类可以创建基本数据类型的对象
	例子:
		var num = new Number(2);
		var str = new String("hello");
		var bool = new Boolean(true);
	    但是在实际应用中千万不要这么干。
	当我们去操作一个基本数据类型的属性和方法时,
    解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,
    操作完成以后再将这个临时对象进行销毁。
    例如:
        var a=1
        a.num=2   //不会报错
        console.log(a.num) //undefined
-----------------------------------------------------------------------------------------
字符串的相关的方法(都不会改变原数组):
	length   获取字符串的长度
	charAt() 根据索引获取指定位置的字符
	charCodeAt()  根据索引获取指定的字符编码
    trim() 去除字符串两侧空格
	String.fromCharCode()  根据字符编码获取字符
    concat()  可以用来连接两个和多个字符串
 	indexOf()和lastIndexOf():
	  从一个字符串中检索指定内容
	  需要一个字符串作为参数,这个字符串就是要检索的内容,
	  如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1。
      可以指定一个第二个参数,来表示开始查找的位置
	  indexOf()是从前向后找
	  lastIndexOf()是从后向前找
	slice():
	  可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量
	  参数:
		第一个:截取开始的位置(包括开始)
		第二个:截取结束的位置(不包括结束)
		可以省略第二个参数,如果省略则一直截取到最后
		可以传负数,如果是负数则从后往前数
	substr()  和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量
	substring():
	  和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0,
	  substring()中如果第二个参数小于第一个,自动调整位置
	toLowerCase() 将字符串转换为小写并返回
	toUpperCase() 将字符串转换为大写并返回
	split():
	  可以根据指定内容将一个字符串拆分为一个数组
	  参数:
		需要一个字符串作为参数,将会根据字符串去拆分数组
		可以接收一个正则表达式,此时会根据正则表达式去拆分数组	
	match():
	  可以将字符串中和正则表达式匹配的内容提取出来
	  参数:
		正则表达式,可以根据该正则表达式将字符串中符合要求的内容提取出来
		并且封装到一个数组中返回
	replace():  
	  可以将字符串中指定内容替换为新的内容
	  参数:
		第一个:被替换的内容,可以是一个正则表达式
		第二个:替换的新内容	
      默认只会替换第一个,所以想全替换的时候,可以使用全局匹配
	search():
	  可以根据正则表达式去字符串中查找指定的内容
	  参数:
		正则表达式,将会根据该表达式查询内容,
		并且将第一个匹配到的内容的索引返回,如果没有匹配到任何内容

-----------------------------------------------------------------------------------------正则表达式:
   正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,
   也可以将一个字符串中符合规则的内容提取出来。
   创建正则表达式:
	  1. var reg = new RegExp("正则","匹配模式");
	  2. var reg = /正则表达式/匹配模式
         typeof reg返回Object
         reg.test(被检测的字符串) 如果匹配返回true不匹配返回false
   语法:
      匹配模式:
	    i:忽略大小写
		g:全局匹配模式
		设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求
      在正则表达式中使用\作为转义字符,\\表示\,.表示任意字符,检查是否含有.:\.
	  正则语法:                       	
			| 或                      \w  任意字符、数字(相当于[A-z 0-9])    
			[] 或                     \W  除了字母、数字([^A-z 0-9])
			[^ ] 除了                 \d  任意的数字[0-9]
			[a-z]任意小写字母          \D  除了数字 [ ^0-9 ]
			[A-Z]任意大写字母          \s  空格       \S  除了空格
			[A-z]任意字母              \B  除了单词边界
			[0-9] 任意数字             \b 单词边界
        量词:
            通过量词可以设置一个内容出现的次数
            量词只对它前边的一个内容起作用
            {n}至少出现n次
            {m,n}出现m到n次
            {m,}m次以上
            +至少一个,相当于{1,}
            *0个或多个,相当于{0,}
            ?0个或1个,相当于{0,1} 
        检查一个字符串的开头语结尾:
            ^表示开头
            $表示结束

-----------------------------------------------------------------------------------------
DOM:
   Document Object Model
   文档对象模型,通过DOM可以来任意来修改网页中各个内容
   文档:
	  文档指的是网页,一个网页就是一个文档
   对象:
	  对象指将网页中的每一个节点都转换为对象
	  转换完对象以后,就可以以一种纯面向对象的形式来操作网页了
   模型:
	  模型用来表示节点和节点之间的关系,方便操作页面
   节点(Node):
	  节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点
	  虽然都是节点,但是节点的类型却是不同的
	  常用的节点
			文档节点 (Document),代表整个网页
			元素节点(Element),代表网页中的标签
			属性节点(Attribute),代表标签中的属性
			文本节点(Text),代表网页中的文本内容     

-----------------------------------------------------------------------------------------
DOM操作:
  DOM查询
	在网页中浏览器已经为我们提供了document对象,
	它代表的是整个网页,它是window对象的属性,可以在页面中直接使用。
  document查询方法:
    document.getElementById("id属性值")
	    根据元素的id属性查询一个元素节点对象
    document.getElementsByName("name属性值")
	    根据元素的name属性值查询一组元素节点对象
        这个方法会给我们返回一个类数组对象,所有查询的元素都会封装到对象中
    document.getElementsByTagName("标签名")
	    根据标签名来查询一组元素节点对象
        这个方法会给我们返回一个类数组对象,所有查询的元素都会封装到对象中
        即使查询到的元素只有一个,也会封装到数组中返回
    document.body
        此属性在document中有一个body属性,它保存的是body的引用
    document.documentElement
        此属性为document的属性,保存的是html根标签
    document.all
        此属性为document的属性,代表页面的所有元素
    document.getElementByClassName()
        可以根据class属性获取一组元素节点对象(该方法不支持IE8)
    document.querySelector()
        需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
        虽然IE8中没有getElementsByClassName(),但是可以使用querySelector()代替
        使用该方法总会返回唯一的元素,如果满足条件的元素有多个,那它只会返回第一个
    document.querySelectorAll()
        该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回
        即使符合条件的元素只有一个,它会返回数组

-----------------------------------------------------------------------------------------
获取元素节点的子节点
	通过具体的元素节点调用
	   元素.firstChild      获取当前元素的第一个子节点
	   元素.lastChild       获取当前元素的最后一个子节点
       元素.previousSibling 获取当前元素的前一个兄弟节点
	   元素.nextSibling     获取当前元素的后一个兄弟节点
       元素.childNodes      获取当前元素的所有子节点,会获取到空白的文本子节点(在ie8及以下不会获取空白文本子节点)
	   元素.parentNode      获取当前元素的父元素
       元素.children        获取当前元素的所有子元素
       元素.getElementsByTagName()    通过标签名查询当前元素的指定后代元素
       元素.previousElementSibling    获取前一个兄弟元素,IE8及以下不支持	
       元素.firstElementChild    获取当前元素的第一个子元素(不支持IE8以下的浏览器)

-----------------------------------------------------------------------------------------
Dom增删改: 
	document.createElement()           可以根据标签名创建一个元素节点对象
	document.createTextNode()          可以根据文本内容创建一个文本节点对象	
	父节点.appendChild(子节点)          向父节点中添加指定的子节点
	父节点.insertBefore(新节点,旧节点)   将一个新的节点插入到旧节点的前边
	父节点.replaceChild(新节点,旧节点)   使用一个新的节点去替换旧节点
	父节点.removeChild(子节点)          删除指定的子节点
    元素.cloneNode(true): 
    复制节点 如括号参数为空或为false,则是浅拷贝,只复制节点本身不复制里面的子节点
             如果是true则复制本身和子节点
-----------------------------------------------------------------------------------------
元素的属性:
  读取元素的属性:
	语法:元素.属性名
   	元素.id  元素.name  元素.value
    注意:class属性不能采用这种方式,读取class属性时需要使用元素.className
          追加class属性: 元素.className+=" 类名" (类名前加个空格)
          追加class属性2:元素.classList.add("类名")
          移除class属性: 元素.classList.remove("类名")
          切换class属性: 元素.classList.remove("类名") (有这个类名就加上没有就删除)
    元素.getAttribute("属性") 该方法主要获取程序员自定义的属性
  修改元素的属性:
	语法:元素.属性名 = 属性值
         元素.setAttribute("属性","值")该方法主要修改程序员自定义的属性
  移除属性:
    元素.removeAttribute("属性") 
  innerHTML
	使用该属性可以获取或设置元素内部的HTML代码,对于自结束的标签,这个属性没有意义
  innerText
    该属性可以获取或设置元素内部的文本内容
    他和innerHTML类似,不同是innerHTML会获取到html标签,而innerText会自动去除标签      
-----------------------------------------------------------------------------------------
事件(Event)
  事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。
  我们可以为事件来绑定回调函数来响应事件。
  绑定事件的方式:
	  1.可以在标签的事件属性中设置相应的JS代码
		 例子:
			<button onclick="js代码。。。">按钮</button>
	  2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件
		 例子:
			<button id="btn">按钮</button>
			<script>
				var btn = document.getElementById("btn");
				btn.onclick = function(){
						
				};
			</script>

----------------------------------------------------------------------------------------		
文档的加载:
   浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。
   如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,
   此时将会无法正常获取到DOM对象,导致DOM操作失败。
	 解决方式一:
		 可以将js代码编写到body的下边
		<body>
			<button id="btn">按钮</button>
			<script>
				var btn = document.getElementById("btn");
				btn.onclick = function(){
				
				};
			</script>
		</body>
	 解决方式二:
		将js代码编写到window.onload = function(){}中
		window.onload 对应的回调函数会在整个页面加载完毕以后才执行,
		所以可以确保代码执行时,DOM对象已经加载完毕了
			<script>
				window.onload = function(){
					var btn = document.getElementById("btn");
					btn.onclick = function(){
					
					};
				};
			</script>	
         
-----------------------------------------------------------------------------------------
comfirm()
用于弹出一个带有确认和取消按钮的提示框
需要一个字符串作为参数,该字符串作为提示文字显示出来
点击确认返回true,点击取消返回false

-----------------------------------------------------------------------------------------
操作内联样式:
  通过JS修改的样式:
   语法:元素.style.样式名 =样式值
   注意:
     如果CSS的样式中含有-,这种名称在JS中式不合法的,
     比如:background-color需要将这种样式名改为驼峰命名法,去掉-,然后将-后的字母大写
     通过style属性设置样式都是内联样式,而内联样式有较高的优先级,所以通过JS修改的样式会立即显示
     但是如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式, 
     此时将会导致JS修改样式失效,所以尽量不要为样式添加!important
     通过style属性设置和读取的都是内联样式,无法读取样式表的样式
  获取元素当前显示样式:
    语法:元素.currentStyle.样式名
         它可以用来读取当前正在显示的样式,如果当前元素没有设置该样式,则获取它的默认值
         提示:只有IE支持,其他浏览器不支持
    语法:元素.getComputedStyle() 
         这个方法来获取元素当前的样式,这个方法是window的方法,可以直接使用,需要两个参数
         第一个:要获取的样式的元素      第二个:可以传一个伪参数,一般传null
         该方法会返回一个对象,对象中封装了当前元素对应的样式(属性),可以通过对象.样式名来读取样式,
         如果获取的样式没有设置,则会获取到真实的值,而不是默认值,
         比如:没有设置width,它不会获取到auto,而是一个长度,但是该方法不支持IE8及以下的浏览器
    注意:通过currentStyle和和getComputedStyle()读取到的样式都是只读的,不能修改,如果要修改必 
         须通过style属性
  其他样式操作的属性:
    clientWidth clientHeight:
         这两个属性可以获取元素的可见宽度于高度,这些包括后面的属性都是不带px的
         返回都是一个数字,可以直接进行计算,会获取元素的高度和宽度,包括内容区和内边距
         这些属性都是只读的,不能修改
    offsetWidth offsetHeight:
         获取元素整个宽度和高度,包括内容区、内边距和边框
    offsetParent:
         可以用来获取当前元素是的定位父元素
         会获取离当前元素最近的开启了定位的祖先元素
         如果所有的祖先元素都没有开启定位,则会返回body
    offsetLeft  offsetTop:
         当前元素相对于其定位父元素的水平,垂直偏移量
    scrollWitdth  scrollHeight:
         可以获取元素整个滚动区域的宽度和高度
    scrollLeft   scrollTop:
         可以获取水平滚动条滚动的距离和垂直滚动条滚动的距离
         document.documentElement.scrollTop/Left 整个页面滚动条滚动的距离
         元素.scrollTop/Left 元素滚动条滚动的距离
    getBoundingClientRect().top/left
         元素距离浏览器的可视距离
    技巧:
        scrollHeight -scrollTop == clientHeight说明垂直滚动条到底了
        scrollWidth - scrollLeft == clientWidth说明水平滚动条到底了

---------------------------------------------------------------------------------------
input元素禁用:
  disabled属性可以设置一个input元素是否禁用
  如果设为true,则元素禁用
  如果设置为false,则元素可用

-----------------------------------------------------------------------------------------
事件对象:
  当事件的响应函数被触发时,浏览器每次都会将一个事件对象(event)作为实参传递进响应函数,
  在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标、键盘哪个键被按下、鼠标滚轮滚动方向……
  event.target表示触发事件的对象 ie8不支持
  event.srcElement也表示触发事件的对象 ie8以下使用
  event.preventDefault()组织默认行为 ie8不支持
  event.returnValue组织默认行为  ie8使用
  return false组织默认行为 都支持
  event.cancelBubble = true; 阻止事件冒泡ie8使用
  event.stopPropagation()  阻止事件冒泡ie8不支持
  clientX可以获取鼠标相对当前可见窗口的x坐标
  clientY可以获取鼠标相对当前可见窗口的y坐标
  pageX,pageY可以获取鼠标相对当前页面的x和y坐标  ie8不支持
  offsetX,offsetY可以获取鼠标相对于当前dom元素的x和y坐标
  在IE8,响应函数被触发时,浏览器不会传递事件对象,
  在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存

-----------------------------------------------------------------------------------------事件的冒泡(Bubble)
   事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,其祖先元素上的同类事件也会触发。
   事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消
   可以将事件对象的cancelBubble设置为true,即可取消冒泡
		元素.事件 = function(event){
			event = event || window.event;
			event.cancelBubble = true; 阻止事件冒泡ie8使用
            event.stopPropagation()  阻止事件冒泡ie8不支持
		};

-----------------------------------------------------------------------------------------
事件的委派:
  我们希望,只绑定一次事件,即可应用到多分元素上
  即使元素是后添加的,我们可以尝试将其绑定给元素的共同祖先元素。
  事件的委派指将事件统一绑定给元素的共同祖先,这样当后代元素的事件被触发时,
  会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
  事件的委派是利用了冒泡,通过委派可以减少事件的绑定次数,挺高程序性能。
  event中的target表示的触发事件的对象
  可以给每个后代元素加一个属性,通过event.target上这个属性值判断是否触发事件

-----------------------------------------------------------------------------------------
事件绑定:
1. button.onclick = function () {
        alert(1);
    };
    button.onclick = function () {
        alert(2);
    };
  普通的绑定后者会对前者进行覆盖,所以它只会弹出2
2. addEvebtListener()  通过这个方法也可以为元素绑定响应函数
  参数:
      1. 事件的字符串,不带on
      2. 回调函数,当时间触发时该函数会被调用
      3. 是否在捕获阶段触发事件,需要一个布尔值,一般情况下,都传false
            button.addEventListener("click", function () {
                alert(1);
            }, false);
            button.addEventListener("click", function () {
                alert(2);
            }, false);
       优点:
             可以同时为一个元素的相同事件同时绑定多个响应函数,
             这样当事件触发时,响应函数将会按照绑定的顺序执行
             一些特定的事件也只能使用该方法绑定
       缺点:
             兼容性问题,IE8及以下没有这个方法
3.attachEvent() 在IE8中可以使用attachEvent()来绑定事件
   参数:
      1. 事件的字符串,要on  2.回调函数
   这个方法也可以同时为一个事件绑定多个处理函数
   不同的是它是后绑定先执行,执行顺序和addEventListener()相反
   这个只有IE8及以下的时候采用
注意:考虑到兼容性问题,可以把他俩做结合
      定义一个函数,用来为指定元素绑定响应函数
      addEventListener()中的this,是绑定事件的对象
      attachEvent()中的this,是window
      需要统一两个方法的this
      参数:
           obj 要绑定事件的对象
           eventStr 事件的字符串(不要on)
           callback 回调函数
       function bind(obj,eventStr,callback){
            if(obj.addEventListener){
                //大部分浏览器
                obj.addEventListener(eventStr,callback,false);
            }else {
                // this是由谁调的方式决定  callback().call(obj)
                //IE8及以下浏览器
                obj.attachEvent("on"+eventStr,function (){
                    callback.call(obj);
                });
            }
        }

-----------------------------------------------------------------------------------------
事件的传播:
   W3C将事件传播分成了三个阶段:
    1. 捕获阶段
       在捕获阶段时,从最外层的祖先元素向目标元素进行事件的捕获,但是默认此时不会触发事件
    2. 目标阶段
       事件捕获到目标元素,捕获结束开始在目标元素上触发事件
    3. 冒泡阶段
       事件从目标元素向他的祖先元素传递,依次触发祖先元素的事件
   注意:
       如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
       IE8及以下的浏览器中没有捕获阶段
       元素.addEventListener("事件类型不加on",function(){},false)

-----------------------------------------------------------------------------------------
鼠标事件:
onclick鼠标点击左键
onmouseover移入事件 会冒泡
onmouseout移出事件  会冒泡
mouseenter移入事件  不会冒泡
mouseleave移出事件  不会冒泡
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousedown鼠标按下
onmousemove鼠标移动
onmouseup鼠标松开
return false取消浏览器默认行为,但对ie8不起作用
在ie8中调用一个元素的setcapture()方法以后,这个元素将会把下次所有的鼠标按下相关事件捕获到自身
releasecapture()对事件捕获释放
setcapture()只有在ie8支持,在火狐不会报错,谷歌会报错
补充:
     禁止使用右键菜单
     document.oncontextmenu=function(){
        return false
     }
     禁止选中文字
     document.onselectstart=function(){
        return false
     }
     窗口大写发生变化触发该事件
     window.onresize=function(){}  
     window.innerWidth表示当前屏幕宽度

-----------------------------------------------------------------------------------------
鼠标滚轮事件:
  火狐滚轮DOMMouseScroll
    1. 注意该事件需要通过addEventListener()函数来绑定
    2. 火狐不支持wheelDelta这个属性,其对应用的是detail这个属性来获取滚动的方向,向上滚动 -3,向下滚动3
    3. 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器的默认行为,一般用return
       false,来取消,但是火狐是用addEventListener(),使用addEventListener()方法来绑定响应函 
       数,取消默认行为不能使用return false。需要使用event来取消默认行为 
       event.preventDefault,但是IE8对此又不支持,如果调用会直接报错,所以我们一般这样写: 
       event.preventDefault && event.preventDefault()
 其他浏览器onwheel
    1. wheelDelta来获取滚轮方向,当向上滚动时,其返回值为120,向下滚动时,其返回值为-120
    2. 用returen false来取消浏览器滚条随滚条移动的情况。

-----------------------------------------------------------------------------------------
滚动条事件:
 onscroll:
    onscroll事件在元素滚动条滚动时触发。滚动条必须存在,否则不会触发。无论以哪种方式让滚动条 
    滚动,只要滚动条滚动,事件都会触发。
    而wheelDelta是鼠标滚轮滚动时触发

-----------------------------------------------------------------------------------------
键盘事件
  按键被按下onkeydown
   1. 对于onkeydown来说如果一直按着某个按键不松手,则事件会被一直触发。
   2. 当onkeydown连续触发时,第一次和第二次之间的间隔稍微长一点,其他的会变得非常快,
      这种设计是为了防止误操作的发生
  按键被松开onkeyup
      键盘事件一般会绑定给一些可以获取焦点的对象或者是document
      keyCode获取按键的unicode编码
  通过它可以判断哪个按键被按下:
      altKey判断alt键是否被按下
      ctrlKey判断ctrl键是否被按下
      shiftKeY判断shift是否被按下

-----------------------------------------------------------------------------------------
Bom:
  BOM浏览器对象模型
  BOM可以使我们通过JS来操作浏览器
  在BOM中提供了一组对象,用来完成对浏览器的操作
  Bom对象:
    Window
       代表的使整个浏览器的窗口,同时window也是网页中的全局对象
    Navigator
       代表的是当前浏览器的信息,通过该对象可以识别不同的浏览器
    Location
       代表的是当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
    History
       代表的是浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不
       能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时才有效
    Screen
       代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关信息
  注意:这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,
       也可直接使用

-----------------------------------------------------------------------------------------
Navigator:
   代表的是当前浏览器的信息,通过该对象可以识别不同的浏览器
   由于历史原因,Navigator对象中大部分属性都已经不能帮助我们识别浏览器了。
   一般我们只会使用userAgent来判断浏览器的信息,userAgent是一个字符串,这个字符串中包含用来
   秒速浏览器信息的内容,不同的浏览器有不同的userAgent。(userAgent等价于浏览器)
   在IE11中已经将微软和IE相关的表示都已经去除了,我们基本已经不能额通过userAgent来识别一个
   浏览器是否是IE了
   虽然不能通过userAgent不能判断,但还可以通过一些浏览器中特有的对象,来判断浏览器的信息,比如 
   ActiveXObject    "ActiveXObject" in window检查window是否有ActiveXObject 

-----------------------------------------------------------------------------------------
History:
   该对象可以用来操作浏览器向前或向后翻转
   length
   属性,可以获取到当前访问的链接数量
   back()
   可以退回到上一个页面,作用和浏览器的回退按钮一样
   forward()
   可以跳转下一个页面,作用和浏览器的前进按钮一样
   go()
   可以用来跳转到指定的页面,需要一个整数作为参数
   1:向前跳转一个页面,相当于forward()
   2:向前跳转两个页面
   -1:向后跳转一个页面,相当于back()
   -2:向后跳转两个页面

-----------------------------------------------------------------------------------------
Location:
   该对象封装了浏览器的地址栏信息
   如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
   如果直接将location属性修改为一个完整的路径,或相对路径则我们页面会自动跳转到该路径,
   并且会生成相应的历史记录    location ="https://www.bilibili.com/"
   location.href 获取或设置整个url
   location.search 返回参数
   assign()方法  
      用来跳转到其他页面,作用和直接修改location一样
      location.assign("https://v.qq.com/");
   reload()方法
      用于重新加载文档,和刷新按钮一样,
      如在括号加true作为参数,则会强制清空缓存刷新页面
   replace()方法 
      可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
      不会生成历史记录,不会使用回退按钮回退

-----------------------------------------------------------------------------------------
定时器:
  如果希望一段程序,每间隔一段时间执行一次,可以使用定时调用
  setInterval()定时调用,可以将一个函数,每隔一段时间执行一次
  参数:
    回调函数,该函数会每隔一段时间被调用一次
    每次调用间隔的时间,单位是毫秒
  返回值:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识。
  clearInterval() 此方法需要一个定时器标识作为参数,这样来关闭对应的定时器
  clearInterval()注意点:
       1. clearInterval()可以接受任意参数
       2. 如果参数是一个有效的定时器的标识,则关闭该定时器
       3. 如果参数不是一个有效的标识,则什么也不做,也不会报错

-----------------------------------------------------------------------------------------
延迟调用:
  setTimeout() 延迟调用一个函数不马上执行,而是隔一段时间后再执行,而且只会执行一次
  延迟调用和定时调用的区别:
     延迟调用只会执行一次,而定时调用会执行多次
     延迟调用和定时调用实际上可以互相代替,在开发中可以根据自己的需求去选择
  clearTimeout()关闭延时调用

-----------------------------------------------------------------------------------------
浏览器本地存储WebStorage
    1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样
    2. 浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
    3. 相关API:
        (1)xxxStorage.setItem('key', 'value'):该方法接受一个键和值作为参数,会把键值对添加到 
           存储中,如果键名存在,则更新其对应的值
        (2)xxxStorage.getItem('key'):该方法接受一个键名作为参数,返回键名对应的值
        (3)xxxStorage.removeItem('key'):该方法接受一个键名作为参数,并把该键名从存储中删除
        (4)xxxStorage.clear():该方法会清空存储中的所有数据
    4. 备注:
        (1)SessionStorage存储的内容会随着浏览器窗口关闭而消失
        (2)LocalStorage存储的内容,需要手动清除才会消失
        (3)xxxStorage.getItem(xxx)如果 xxx 对应的 value 获取不到,那么getItem()的返回值是 
           null
        (4)JSON.parse(null)的结果依然是null
    注意:存储和取值的时候如果是引用数据类型需要用JSON.parse()或JSON.stringify()转换
-----------------------------------------------------------------------------------------
JSON:
  JS中的对象只有JS自己认识,其他的语言都不认识
  JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别
  并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
  javaScript Object Notation JS 对象表示法
  JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,不然就会报错!其他的和JS语法一致! 
  JSON中允许的值
        1.字符串
        2.数 组
        3.布尔值
        4. null
        5.对 象
        6.数 组
   JSON分类:1. 对象{}  2.数组[]
   JSON.parse()
       可以将JSON字符串转换为JS对象
       它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回。
   JSON.stringify()
       可以将一个JS对象装欢为JSON字符串
       需要一个JS对象作为参数,会返回一个JSON字符串
   注意:JSON这个对象在IE7及以下的浏览器中不支持,所以再这些浏览器中调用时会报错。
   eval()
       这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回,但是如果使用eval()执行的字 符串中含有{},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
       eval()这个函数的功能十分强大,可以直接执行一个字符串的JS代码,但是在开发中尽量不要使用,首先它的执行性能比较差,然后它害具有安全隐患。
   那要怎么去兼容IE7及以下的浏览器?
   通过引进一个外部的js文件来处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值