关于javascript:关于JSJavaScript

3次阅读

共计 18735 个字符,预计需要花费 47 分钟才能阅读完成。

支流浏览器的内核

IE:trident
Chrome:webkit/blink
firefox:Gecko
Opera:presto
Safari:webkit

引入 JS 的形式

页面内嵌标签(可在 head 内或 body 内)内部引入(罕用办法)

JS 根本语法

变量:变量申明:申明,赋值合成。繁多 var。(var a=100)命名规定:变量名必须以英文字母,*,$ 结尾 *
变量名能够包含英文字母,,$,数字
不能够用零碎的关键字,保留字作为变量名


值类型(数据类型):不可扭转的原始值(栈数据):Number,Boolean,String,undefined,null
栈内存和栈内存之间赋值是拷贝(互不影响)援用值(堆数据):array,Object,function,..data,RegExp


typeof()可查看数据类型(返回 number,string,boolean,object,undefined,function)类型转换:显式类型转换:Number(mix) 转换不了的就显示为 NaN
                   parseInt(string,radix) string 以 radix 进制为基底转换为 10 进制
                   parseFloat(string)
                   num.toString(radix) num 转为 radix 进制
                   String(mix)
                   Boolean()
     隐式类型转换:isNaN() 先转为 number,再与 NaN 比拟
                   ++/-- +/-(正负)转为数字类型
                   + 转为字符串
                   - * / %  转为数字类型 '1'*1=1
                   && || !
                   < > <= >= 字符串与数字比拟,转为数字再比拟。字符串与字符串比拟,比拟 ascii 码
                   == != 转为数字再比拟
不产生类型转换:===,!==


语句的根本规定:每一句前面要以分号完结(除函数,for 语句,if 语句...)js 语法错误(低级谬误,逻辑谬误)会引发后续代码终止,但不会影响其余 js 代码块
书写格局要标准,'=+/-' 两边要有空格

运算操作符:'+':数学运算,字符串连贯。任何数据类型加字符串都等于字符串
'-','*','/','%','=','()':'()' 优先级最高,'=' 优先级最低
 '++','--','+=','-=','/=','*=','%='
e.g. var a = 10 ; var b = ++a - 1 + a++(此时 b 等于 21,a 等于 12)var a = 1 ; var b = a-- + --a(此时 b 等于 0(先算 --a,而后 b =0+0=0),a 等于 -1)比拟运算符:'>','<','==','>=','<=','!='(比拟后果为 boolean 值)NaN!=NaN

逻辑运算符:'&&'(碰到假就停),'||'(碰到真就停),'!'(运算后果为实在的值)e.g. var a = 1 && 2+2(a 为 4)var a = 0 && 2+2(a 为 0)var a = 2+1 && 0(a 为 0)var a = 1 || 3(a 为 1)var a = 0 || 2(a 为 2)(window.foo || (window.foo='bar'))(window.foo 的值为 bar(先看括号的))被认定为 false 的值:undefined,null,NaN,'',0,false

条件语句:if,if else if,switch case,break,continue
循环语句:for,while,do while

函数

定义:函数申明(function xxx(){})函数表达式(命名函数表达式:var test=function xxx(){}, 匿名函数表达式(罕用):var test=function (){})组成模式:函数名称(小驼峰准则 如 theFirstName)参数:形参(获取形参长度:函数名.length),实参(arguments 示意的是实参列表, 获取实参长度:arguments.length)返回值


e.g.1 求 5 的阶乘(递归)function mul(n){if(n==1 || n==0)
        {return 1}
        return n*mul(n-1);
    }
    mul(5);



作用域

作用域定义:变量和函数失效的区域(存储了运行期上下文的汇合)作用域的拜访程序:函数外面的能够拜访里面的值(外面的能够拜访里面的,里面的不能拜访外面的)函数被定义时,会在作用域链中生成一个 GO 对象
函数被执行时,会在作用域链中多生成一个 AO 对象,此时 0 号地位是 AO,1 号地位是 GO


当多个函数为蕴含关系时,各函数作用域链的变动:e.g. function a(){function b(){function c(){ }
          c();}
      b();}
    a();

   a defined  a.[[scope]] --> 0:GO
   a doing  a.[[scope]] --> 0:aAO 1:GO
   b defined  b.[[scope]] --> 0:aAO 1:GO
   b doing  b.[[scope]] --> 0:bAO 1:aAO 2:GO 
   c defined  c.[[scope]] --> 0:bAO 1:aAO 2:GO
   c doing  c.[[scope]] --> 0:cAO 1:bAO 2:aAO 3:GO
   
   with 会扭转作用域链:with(拜访的对象){执行的代码} 
                      若拜访的对象没有对应的变量,则在本来执行的这个函数体中找变量。e.g.
   var obj={name:'obj'};
   function test(){
        var age=123;
        var name='scope';
        with(obj){console.log(name);  // 输入 obj
               console.log(age);  // 输入 123
        }
   }       

JS 三部曲(预编译重点)

语法分析
预编译(产生在函数执行的前一刻)解释执行


预编译:函数申明整体晋升
        变量申明晋升
预编译前奏:imply global 暗示全局变量:即任何变量,如果变量未经申明就赋值,此变量为全局对象(window)所有(var a=b=123(b 为经申明就赋值,归 window 所有。所以 window.a 为 undefined,window.b 为 123))所有申明的全局变量,全是 window 的属性(var a=123 => window.a=123)预编译过程四部曲:创立 AO 对象
             找形参和变量申明,将变量和形参名作为 AO 属性名,值为 undefined
             将实参值和形参对立
             在函数体外面找函数申明,值赋予函数体

e.g. function fn(a){                 1. 创立 AO 对象(执行期上下文)console.log(a);               2. 找形参和变量申明
    var a=123;                      AO{a:undefined,b:undefined}
    console.log(a);               3. 将实参和形参对立
    function a(){};                 AO{a:1,b:undefined}
    console.log(a);               4. 找函数申明
    var b=function(){}              AO{a:function a(){},b:undefined,d:function d(){}}
    console.log(b);
    function d(){}
    }
    fn(1)

所以第一个 console.log(a)打印的是 function a(){}
 此时执行 var a=123,所以此时 AO{a:123,b:undefined,d:function d(){}}
第二个 console.log(a)打印的是 123
此时不必再看 function a(){}(因为预编译曾经看过了)第三个 console.log(a)打印的是 123
此时执行 var b=function (){}, 所以此时 AO{a:123,b:function (){},d:function d(){}}
第四个 console.log(b)打印的是 function (){}

若一个变量未经申明就赋值,会把此变量放到 GO 对象(window)中

e.g.1 console.log(test);
   function test(test){console.log(test);
    var test=234;
    console.log(test);
    function test(){};
   }
   test(1);
   var test=123;

   先创立 GO 对象:GO{test:function (){...}}
   再创立 AO 对象:AO{test:function (){}}

   所以第一个 console.log(test)为 function(){}
   第二个为 function(){}
   执行 var test=234, 所以 AO{test:234}
   第三个为 234

   e.g.2 global=100;
         function fn(){console.log(global);
         global=200;
         console.log(global);
         var global=300;
         }
         fn();
         var global;

         先创立 GO:{global:100}
         再创立 AO:{global:undefined}
         此时第一个输入为 undefined(AO 中有的就先从 AO 中找)再执行 global=200; 此时 AO:{global:200}
         所以第二个输入为 200

  e.g.3 function test(){console.log(b);
            if(a){var b=100;}
                console.log(b);
                c=234;
                console.log(c);
                }
                var a;
                test();
                a=10;
                console.log(c);

                先创立 GO:{a:undefined}
                再创立 AO:{b:undefined}
                第一个输入为 undefined
                此时 a 为 undefined,不能执行 var b=100
                所以第二个输入为 undefined
                执行 c =234,AO 里没有 c,则把变量 c 增加到 GO 中,此时 GO{a:undefined,c:234}
                第三个输入为 234
                再执行 a =10,此时 GO{a:10,c:234}
                第四个输入为 234

 e.g.4 var x=1;
       if(function f(){}){x+=typeof f;}
       console.log(x);

       因为 (function f(){}) 为表达式,所以 f 是 undefined
       所以 x 输入为 1undefined
       (未经申明的变量放在 typeof 中不会报错,为 undefined)


   对于 GO 和 AO 对象,若 AO 上没有相应变量,则再去 GO 上找
   预编译时会疏忽掉判断的语句
   GO 和 AO 对象实则是执行期上下文

立刻执行函数

立刻执行函数次要针对初始化性能的函数(执行完就被销毁)(function (形参(可有可无)){}(实参(可有可无)))
只有表达式能力被执行符号执行
如:var test=function (){}();
    +function test(){}();
    (function test(){})();

闭包(重点)

闭包的生成:当外部函数被保留到内部的时候
闭包的防备:闭包会导致多个执行函数共用一个私有变量,如果不是非凡须要,应尽量避免这种状况产生
闭包的作用:实现私有变量(函数累加器)能够做缓存(存储构造)能够实现封装,属性私有化
           模块化开发,避免净化全局变量
可用立刻执行函数解决闭包

e.g. 给 4 个 li 绑定点击事件
    var li=document.getElementByTagName('li');
     for(var i=0;i<li.length;i++){(function (j){li[j].onclick=function(){console.log(j)
            }(i))
    }

对象

属性的增,删,改,查:增:对象名. 属性名 = 属性值
删:delete 对象名. 要删除的属性名
改:对象名. 要批改的属性名 = 新的属性值
查:对象名. 要查看的属性名

对象的创立办法:1. 对象字面量 / 对象间接量 var obj={}
2. 构造函数(大驼峰命名规定:如 TheFirstName):零碎自带的构造函数 Object():var obj=new Object()
                                             自定义:function 函数名(){this. 属性名 = 属性值...}
                                                    var 对象名 = new 函数名()
3. var obj=Object.create(原型 /null)(创建对象的同时可自定义原型)革新函数的外部原理:1. 在函数体最后面隐式的加上 this={}(AO:{this:{xxx}})2. 执行 this.xxx=xxx
                   3. 隐式的返回 this(构造函数中返回值不能返回原始值,会疏忽掉,主动返回 this)包装类:new String()
         new Boolean()
         new Number()
 e.g. var str='abc';
      str+=1;
      var test=typeof(str);
      if(test.length==6){
            test.sign='typeof 的返回后果可能为 String';(原始值赋属性值要调用包装类,赋和没赋一样)//new String(test).sign='xxx' 随后 delete
       }
       //new String(test).sign(为 undefined)cosnole.log(test.sign);
        输入的后果为 undefined
  

原型

原型是 function 对象的一个属性,它定义了构造函数制作进去的对象的公共先人
通过该构造函数产生的对象,能够继承该原型的属性和办法
原型也是对象
利用原型能够提取私有的属性
对象查看原型:隐式属性__proto__(函数名.prototype)对象查看对象的构造函数:constructor
判断是否为本身的属性:对象名.hasOwnProperty(属性值)

e.g. Person.prototype.name='sunny'
     function Preson(){}
     var person=new Preson();
     Preson.prototype.name='cherry';
     此时 person.name='cherry'
     
     Person.prototype.name='sunny'
     function Preson(){}
     var person=new Preson();
     Preson.prototype.name={name:'cherry'}
     相似于
     var obj={name:'a'};
     var obj1=obj;
     obj={name:'b'};(新开的空间)所以此时 person.name 还是等于 'sunny'(此时的__proto__还是指向原来的 Person.prototype)原型链中绝大多数对象最终都会继承自 Object.prototype

undefined 和 null 没有原型

扭转 this 指向:call,apply
call:原来的函数名.call(this 要指向的函数名, 参数)apply:原来的函数名.apply(this 要指向的函数名,[参数])call 和 apply 的区别:传参数的模式不同
                   call 是要把实参依照形参的个数传进去
                   apply 是传一个 arguments

继承模式

1. 传统模式(原型链):过多的继承了没用的属性
2. 借用构造函数:不能继承借用构造函数的原型
                每次构造函数都要多走一个函数
3. 共享原型:不能轻易改变本人的原型
4. 圣杯模式
   第一种写法:function inherit(Target,Origin){function F(){};
        F.prototype=Origin.prototype;
        Target.prototype=F.prototype;
        Target.prototype.constructor=Target;
        Target.prototype.uber=Origin.prototype;
    }
   第二种写法:var inherit=(function (){var F=function (){};
        return function(Target,Origin){
             F.prototype=Origin.prototype;
             Target.prototype=F.prototype;
             Target.prototype.constructor=Target;
             Target.prototype.uber=Origin.prototype;
        }
   }())
     

命名空间

治理变量,避免净化全局,实用于模块化开发

可应用闭包的办法实现变量私有化,从而避免变量净化
var name='bcd';
var init=(function (){
    var name='abc';
    function callName(){console.log(name);
    }
    return function(){callName();
    }
}())
init();
此时打印进去的 name 还是 abc

还可应用 Webpack 等
  

JS 实现链式调用模式(仿 JQ)

如:obj.eat().smoke().drink()

在每个办法前面 return this

对象枚举

数组遍历:for 循环数组长度

对象遍历:for in 循环
for(var xxx(自定义) in 对象名){console.log(对象名[xxx])}

辨别数组, 对象的三种办法

办法一:instanceof
判断 A 对象是不是 B 构造函数结构进去的(判断 A 对象的原型链上有没有 B 的原型):A instanceof B
数组:[] instanceof Array --> true 
对象:{} instanceof Object --> true

办法二:constructor
对象:obj={},obj.constructor --> function Object()
数组:arr=[],arr.constructor --> function Array()

办法三:toString()
数组:Object.prototype.toString.call([]) --> [object Array]
对象:Object.prototype.toString.call([]) --> [object Object]

对于 this

函数预编译过程 this -> window
全局作用域里 this -> window
call/apply 可扭转函数运行时的指向
obj.func();   func()外面的 this 指向 obj(谁调用 this 指向谁)e.g.1 var name='222';
     var a={
        name:'111',
        say:function(){console.log(this.name);
         }
      }
      var fun=a.say;
      fun();  // 全局调用
      a.say(); // a 调用
      var b={
          name:'333',
          say:function(fun){fun();
          }
       }
       b.say(a.say);  // 没有阐明是 this 调用,只是把 a.say 这个办法传进来执行(相当于借用这个办法在 b 外面执行),此时还是全局调用
       b.say=a.say;
       b.say();  // 此时为 b 调用
       
       顺次的输入后果为:222,111,222,333
  
 e.g.2 var foo=123;
        function print(){
            this.foo=234;
            console.log(foo);
        }
        print();
        
        执行 this.foo=234 时,此时 this 指向 window,扭转 GO 中 foo 的值为 234
        所以输入后果为 234
        
  若把上题的 print()改为 new print():因为此时的 this=Object.create(print.prototype),this 不指向 window 了
  所以此时输入后果为 123
  
  e.g.3 var a=5;
        function test(){
            a=0;
            alert(a);
            alert(this.a);
            var a;
            alert(a);
        }
        test();  顺次输入 0 5 0
        new test(); 顺次输入 0 undefined(this 下面没有 a)0
        
  e.g.4 var bar={a:'002'};
        function print(){
            bar.a='a';
            Object.prototype.b='b';
            return function inner(){console.log(bar.a);
            console.log(bar.b);
            }
        }
        print()();(相当于先返回一个函数,再进行函数执行)顺次输入为 a,b
        
       
arguments.callee:会指向本人的援用。援用该函数的函数体内的以后正在执行的函数。当函数名称未知时,例如在没有名称的函数表达式中(也称为“匿名函数”),此性能很有用。e.g. var num=(function(n){if(n==1){return 1}
         return n * arguments.callee(n-1)
     }(100))
                    
 func.caller:返回调用指定函数的函数
 
 留神:arguments.callee 和 func.caller 在严格模式下都不能应用
 

克隆

    浅层克隆和深层克隆的区别:浅层克隆:当克隆援用值时,两个对象会共用一个援用地址,造成互相的烦扰,即我改,它也改
    深层克隆:克隆进去的对象和原来的对象是互相独立的,互不影响。也就是对新对象的批改都不会反映到原对象中
    
    浅层克隆:function clone(origin,target){var target=target || {};
        for(var prop in origin){target[prop]=origin[prop];
          }
          return target;
     }

    深层克隆:实现步骤:1. 判断是不是原始值(typeof)2. 判断是数组还是对象(instanceof,toString(举荐应用),constructor)3. 建设相应的数组或对象
    4. 递归
    function deepClone(origin,target){var target=target || {};
            var toStr=Object.prototype.toString;
            var arrStr="[object Array]";
            for(var prop in origin){if(origin.hasOwnProperty(prop)){  // 要克隆本身的属性
                        if(origin[prop] !== "null" && typeof(origin[prop])=='object'){if(toStr.call(origin[prop])==arrStr){ // 克隆的属性是个数组 
                                 target[prop]=[];  // 新建一个数组}
                             else{  // 克隆的属性是个对象
                                 target[prop]={};   // 新建一个对象}
                            deepClone(origin[prop],target[prop]) 
                        }
                        else{  // 原始值间接拷贝
                            target[prop]=origin[prop];
                        } 
             }    
        }
      

数组和类数组

创立数组的办法:var arr=[];
var arr=new Array(1,2,3,4);
var arr=new Array(10);  
new Array():当为一个参数 n 时示意新开一个长度为 n 的数组空间
             当为多个参数时示意数组里的值
  
 数组的读和写:arr[n]:读,但不能够溢出读,要不然后果为 undefined
 arr[n]=xxx:写,能够溢出写
 
 数组罕用的办法:会扭转原数组的:push(在数组开端增加数据)pop(剪切数组开端的数据)shift(剪切数组后面的数据)unshift(在数组后面增加数据)sort(数据排序,默认升序):arr.sort(function(a,b){return x(若 x 为正数时,那么后面的数放在后面。若 x 为负数,那么前面的数放在后面。若 x 为 0,则不动。可间接利用 return a- b 进行升序,return b- a 进行降序)})
                                          可利用 sort 生成一个乱序数组:xxx.sort(function(){return Math.random()-0.5 })
                reverse(数据反转倒序)splice(切片):splice(从第几位开始,截取多少长度,在切口处增加新的数据)
 不会扭转原数组的:concat(数组拼接)join(连贯):join('x')依照 'x' 来连贯数组里的数据
                  split(拆分):solit('x')依照 'x' 来拆分数组里的数据,拆分为字符串
                  toString(变成字符串)slice(截取):slice(从该位开始截取,截取到该位)类数组:能够利用属性名模仿数组的个性
 能够动静的增长 length 属性
 如果强行让类数组调用 push 办法,则会依据 length 属性值的地位进行属性的裁减
 属性要为索引(数字)属性,必须有 length 属性,最好加上 push  
 e.g. var obj={
        "2" : "a",
        "3" : "b",
        "length" : 2,
        "push" : Array.prototype.push
        }
        obj.push('c'); 
        obj.push('d');
        输入后果 obj
        
       push 的原理是:Array.prototype.push=function(target){this[this.length]=target;
            this.length++;
       }
       所以 obj.push('c'),在这个 obj 中相当于 obj[obj.length(即为 2)]='c',而后再 length++
       随后 obj.push('d'),相当于 obj[3]='d'
       所以输入的 obj 为{
                        "2" : "c",
                        "3" : "d",
                        "length" : 2,
                        "push" : Array.prototype.push
                      }
        
        
 实现数组的去重(在原型链上实现):Array.prototype.unique=function(){var temp={};
        var arr=[];  // 搁置去重完后的数组
        var len=this.length;
        for(var i=0;i<len;i++){if(!temp[this[i]]){  // 若没有对应的属性值
                      temp[this[i]]='abc';
                      arr.push(this[i]);
                }
       }
     return arr;  
 }
 

Try…catch

在 try 外面的产生谬误,不会执行谬误后的 try 外面的代码,但还会仍然执行里面的代码
try{}catch(e){

}

常见的错误信息(error.name 的六种对应信息):1. EvalError:eval()的应用与定义不统一
2. RangeError:数值越界
3. ReferenceError:非法或不能辨认的援用数值
4. SyntaxError:产生语法解析谬误
5. TypeError:操作数类型谬误
6. URLError:URL 处理函数使用不当  

es5 严格模式

"use strict"(要写在页面逻辑的最顶端)不再兼容 es3 的一些不规则语法,应用全新的 es5 标准。两种用法:全局严格模式
         部分函数内严格模式(举荐)"use strict" 就是一行字符串,不会对不兼容严格模式的浏览器产生影响。不反对 with,arguments,callee,func,caller,变量赋值前必须申明,部分 this 必须被赋值(Person.call(null/undefined)赋值什么就是什么),回绝反复属性和参数

DOM 操作

DOM 定义了示意和批改文档所需的办法。DOM 对象即为宿主对象,由浏览器厂商定义。用来操作 html 和 xml 性能的一类对象的汇合。对节点的增删改查
查:(除了 getElementsById 匹配进去是一个,其余匹配进去都是类数组(要在开端加上[n(0,1,2,...)]))document.getElementById('id 名') 依据元素 id 匹配相应的元素(在 IE8 以下的浏览器不辨别 id 名大小写)document.getElementsByTagName('标签名') 依据元素标签名匹配相应的元素
     document.getElementsByName('name 名') 依据元素的标签 name 匹配相应的元素
     document.getElementsByClassName('类名') 依据元素标签名匹配相应的元素(在 IE8 和 IE8 以下的浏览器没有,能够多个 class 一起)document.querySelector('CSS 选择器字符串') 匹配指定 CSS 选择器的一个元素(在 IE7 和 IE7 以下的版本没有)不能实时更新
     document.querySelectorAll('CSS 选择器字符串') 匹配指定 CSS 选择器的一组元素(在 IE7 和 IE7 以下的版本没有)不能实时更新
增:document.createElement():创立元素节点
    document.createTextNode():创立文本节点
    document.createComment():创立正文节点
    document.createDocumentFragment():创立虚构的节点对象(可在其中增加 DOM 节点以构建屏幕外 DOM 树)插:要增加到的区域.appendChild(要增加的节点):从前面增加一个子节点到页面(是一种剪切操作)要增加到的区域.insertBefore(要增加的节点,要在此节点前增加的节点):从后面增加一个子节点到页面
    封装函数 insertAfter():Element.prototype.insertAfter(targetNode,afterNode){
        var beforeNode=afterNode.nextElementSibling;
        if(beforeNode==null){  // 若是最初一个节点,则间接在其前面插入
            this.appendChild(targetNode);
        }
        else{   // 在要插的下一个节点前插入(相当于插在要插节点的前面)this.insertBefort(targetNode,beforeNode);
       }
    }
删:父节点.removeChild():父节点移除子节点(剪切操作)节点.remove():节点本人移除本人(删除操作)替换:父节点.replaceChild(new,origin):替换子节点
       
遍历节点树:parentNode:父节点(最顶端的 parentNode 为 #document)childNodes:子节点们
firstChild:第一个子节点
lastChild:最初一个子节点
nextSibling:后一个兄弟节点
previousSibling:前一个兄弟节点

节点的类型:元素节点(1)属性节点(2)文本节点(3)正文节点(8)document(9)DocumentFragment(11)基于元素节点树的遍历:parentElement:返回以后元素的父元素节点(IE 不兼容)children:只返回以后元素的元素子节点
node.childElementCount(相当于 node.children.length):返回以后元素节点的子元素个数
firstElementChild:返回第一个元素节点(IE 不兼容)lastElementChild:返回最初一个元素节点(IE 不兼容)nextElementSibling:返回后一个兄弟元素节点
previousElementSibling:返回前一个兄弟元素节点(IE 不兼容都是指 IE9 和 IE9 以下浏览器不兼容)节点的四个属性:nodeName:元素的标签名,以大写模式示意,只读
nodeValue:Text 节点或 Comment 节点的文本内容,可读写
nodeType:该节点的类型,只读
attribute:Element 节点的属性汇合

节点的一个办法:Node.hasChildNodes()(判断是否有子节点)Element 节点的一些属性:innerHTML:增加 HTML 构造内容
innerText/textContent:增加文本构造内容(innerText 火狐不兼容,textContent IE 老版本不好使)Element 节点的一些办法:ele.setAttribute(属性名, 属性值):设置节点属性
ele.getAttribute(属性名):获取节点属性
     

date(日期)对象

零碎提供的
var date=new Date();
具体性能办法可参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

定时器 , 延时器

设置定时器:定时器名 =setInterval(function(){.....},1000)

革除定时器:clearInterval(定时器名)

设置延时器:延时器名 =setTimeout(function(){.....},1000)

革除延时器:clearInterval(延时器名)

获取窗口属性,dom 尺寸

查看滚动条的滚动间隔:
window.pageXOffset/pageYOffset(横向 / 纵向)(IE8/IE8 以下不兼容)document.body/documentElement.scrollLeft/scrollTop(兼容性凌乱)(应用的时候可两者相交融(相加),适应兼容性)如:document.body.scrollLeft+document.documentElement.scrollLeft

封装兼容性办法:getScrollOffset(){if(0 && window.pageXOffset){
                        return{
                            x:window.pageXOffset,
                            y:window.pageYOffset
                        }
                     }  
                     else{
                         return{
                            x:document.body.scrollLeft+document.documentElement.scrollLeft,
                            y:document.body.scrollTop+document.documentElement.scrollTop
                         }
                     }
               }
       
       
查看视口的尺寸:window.innerWidth/innerHeight(查看窗口的宽高)(IE8/IE8 以下不兼容)document.documentElement.clientWidth/clientHeight(规范模式下任何浏览器兼容)document.body.clientWidth/clientHeight(实用于怪异模式下的浏览器)判断是否为怪异模式:document.compatMode:CSS1Compat(失常模式),backCompat(怪异模式)封装兼容性办法:getViewportOffset(){if(0 && window.innerWidth){
                        return {
                            w:window.innerWidth,
                            h:window.innerHeight
                        }
                    }
                    else{if(document.compatMode==='BackCompat'){  // 怪异模式下
                            return {
                                w:document.body.clientWidth,
                                h:document.body.clientHeight
                            }
                        }
                        else{
                            return {
                                w:document.documentElement.clientWidth,
                                h:document.documentElement.clientHeight,
                            }
                        }
                    }
              }


查看元素的几何尺寸:domEle.getBoundingClientRect()
                   返回一个对象,蕴含 left,top,right,bottom,width,height 等属性(但 width,height 在 IE 老版本中没有显示)返回后果不实时
                
查看元素的尺寸:dom.offsetWidth,dom.offsetHeight
查看元素的地位:dom.offsetLeft,dom.offsetTop
               dom.offsetParent(返回最近的有定位的父级,若无则返回 body。body.offsetParent 返回 null)封装函数:getElementPosition(求绝对于文档的坐标)使滚动条滚动的三个办法:scroll(x,y):滚动到...
                      scrollTo(x,y):滚动到...
                      scrollBy(x,y):滚动了...(会累加)

脚本化 CSS

读写元素 css 属性:dom.style.prop
可读写行间款式,没有兼容性问题,碰到 float 这样的保留字属性,后面应加 css(即 float --> cssFloat)复合属性尽量拆解
组合单词变成小驼峰式写法

查问计算款式:window.getComputedStyle(ele,null)[prop]
计算款式只读
返回的计算款式的值都是绝对值,没有绝对单位
IE8 及 IE8 以下不兼容 
null 用在获取伪元素时,扭转 null(如:window.getComputedStyle(ele,'after').width)查问款式(IE8 及 IE8 以下可用,IE 独有):ele.currentStyle.prop
计算款式只读
返回的计算款式的值不是通过转换的绝对值

封装兼容性办法:getStyle(ele,prop){if(window.getComputedStyle){return window.getComputedStyle(ele,null)[prop]; 
                    }
                    else{return ele.currentStyle.prop;}
                }
                

事件

 绑定事处理函数:ele.onxxx=function(e){} 兼容性很好,然而一个元素的同一个工夫上只能绑定一个处理程序  this 指向元素自身
 obj.addEventListener(type,fn,false){} IE9 以下不兼容,可为一个事件绑定多个处理程序  this 指向元素自身
 obj.attachEvent('on'+type,fn){} IE 独有,一个事件同样能够绑定多个处理程序  this 指向 window
 
 封装兼容性的函数办法:addEvent(ele,type,handle){if(ele.addEventListener){ele.addEventListener(type,handle,false);
                        }
                        else if(ele.attachEvent){ele.attachEvent('on'+type,function(){handle.call(ele);
                            })     
                        }
                        else{ele['on'+type]=handle;
                        }
                     }
                     
解除事件处理函数:ele.onclick=false/null/''
ele.removeEventListener(type,fn,false)
ele.detachEvent('on'+type,fn)
 
事件处理模型:事件冒泡:构造上(非视觉上)嵌套关系的元素,会存在事件冒泡的性能,即同一事件,自子元素冒泡向父元素(自底向上)(focus,blur,change,submit,reset,selectd 等事件不冒泡)勾销冒泡事件产生:e.stopPropagation()(不反对 IE9 以下的版本)e.cancelBubble=true(IE 独有)事件捕捉:构造上(非视觉上)嵌套的关系的元素,会存在事件捕捉的性能,即同一事件,自父元素捕捉至子元素(事件源元素)(自顶向下)IE 没有捕捉事件
把 addEventlistener 中第三个参数改为 true 可触发事件捕捉

触发程序:先捕捉后冒泡

阻止默认事件(表单提交,a 标签跳转,右键菜单等):return false:以对象属性的形式注册的事件才失效
e.preventDefault()(IE9 以下不兼容)e.returnValue=false(兼容 IE9)事件对象:event(非 IE 浏览器都有)|| window.event(用于 IE 浏览器)事件源对象:event.target(火狐只有这个)event.srcElement(IE 只有这个)下面两种 chrome 都有

事件委托:利用事件冒泡和事件源对象进行解决
长处:性能不须要循环所有的元素一个个绑定事件
      灵便,当有新的元素时不须要从新绑定事件
      
事件分类:鼠标事件:click,mousedown,mousemove,mouseup,contextmenu,mouseover,mouseout,mouseenter,mouseleave
event 中的 button 属性可辨别鼠标按键(左键为 0,右键为 2)键盘事件:keydown,keyup,keypress(keydown > keypress > keyup)keydown 和 keypress 的区别:keydown 可响应任意键盘按键
                        keypress 只响应字符类键盘按键,可返回 ASCII 码并转换成相应字符
                        
文本操作事件:input(实时获取文本的值),focus,blur,change(失焦后才获取文本的值)窗体操作类(window 上的事件):scroll,load

JSON

一种传输数据的格局(以对象为样板,实质上是对象,但用处有区别,对象就是本地用的,json 是用来传输的)JSON 中,属性名必须带双引号
JSON.parse():string -> json
JSON.stringfy():json -> string

异步加载 js

js 加载的毛病:加载工具办法没必要阻塞文档,使得 js 加载会影响页面效率,一旦网速不好,那么整个网站将期待 js 加载而不进行后续渲染等工作

js 异步加载的三种计划:1. defer 异步加载,等到 dom 文档全副解析完才会被执行。只有 IE 能用,也可将代码写到外部。2. async 异步加载,加载完就执行,async 只能加载内部脚本,不能把 js 写在 script 标签里
3. 创立 script,插入到 DOM 中,加载结束后 callback(其中第一和第二个办法执行时也不阻塞页面)

js 加载的工夫线

1. 创立 Document 对象,开始解析 web 页面。解析 HTML 元素和他们的文本内容后增加 Element 对象和 Text 节点到文档中。(document.readyState='loading')2. 遇到 link 内部 css,创立线程加载,并持续解析文档
3. 遇到 script 内部 js,并且没有设置 async,defer,浏览器加载,并阻塞,期待 js 加载实现并执行该脚本,而后持续解析文档
4. 遇到 script 内部 js,并且设置有 async,defer,浏览器创立线程加载,并持续解析文档。对于 async 属性的脚本,脚本加载实现后立刻执行。(异步禁止应用 document.write())5. 遇到 img 等,先失常解析 dom 构造,而后浏览器异步加载 src,并持续解析文档
6. 当文档解析实现,document.readyState='interactive'
7. 文档解析实现后,所有设置有 defer 的脚本会依照程序执行
8. document 对象触发 DOMContentLoaded 事件,标记着程序执行从同步脚本执行阶段,转化为事件驱动阶段
9. 当所有 async 的脚本加载实现并执行后,img 等加载实现后,document.readyState='complete',window 对象触发 load

正则表达式

转义字符:'\'
/^ 结尾, 结尾 $/
正则表达式作用:匹配特殊字符或有非凡搭配准则的字符的最佳抉择

两种创立形式:间接量(举荐):var reg=/.../(前面可加 i(疏忽大小写)/g(全局匹配)/m(多行匹配))new RegExp():var reg=new RegExp('...','i/g/m')
             
正则表达式上的办法:reg.test(str)(检索字符串中指定的值。返回 true 或 false)reg.exec(str)(检索字符串中指定的值。返回找到的值,并确定其地位)...
                   
反对正则表达式的 string 对象的办法:str.match(reg)(在字符串内检索指定的值,或找到一个或多个正则表达式的匹配)str.search(reg)(检索与正则表达式相匹配的值。返回 str 中第一个与 reg 相匹配的子串的起始地位,若没有找到任何匹配的子串,则返 -1)str.replace(reg/str,replacement)(用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串)...

正则表达式中一些元字符对应的表达式:\w===[0-9A-z_],\W===[^\w]
                                  \d===[0-9],\D===[^\d]
                                  \s===[\t\n\r\v\f],\S===[^\s]
                                  \b=== 单词边界,\B=== 非单词边界
                                  .===[^\r\n]
                                  
正则表达式的一些量词:n+(呈现一次到屡次)n*(呈现 0 次到屡次)n?(呈现 0 到 1 次)n{x}(呈现 x 次)n{x,y}(呈现 x 到 y 次)以上量词遵循贪心匹配准则(尽可能匹配多的)正向预查(从左到右进行匹配):?=xxx(匹配前面跟着 xxx 的货色)?!xxx(匹配前面不跟着 xxx 的货色)负向预查(从右到左进行匹配):?<=xxx(匹配紧跟 xxx 前面的货色)?<!xxx(不匹配紧跟 xxx 前面的货色)e.g.1 测验一个字符串首尾是否含有数字
        var reg=/^\d|\d$/g;
        var str='123abc';
        reg.test(str) -> true
        
e.g.2 测验一个字符串首尾是否都含有数字
        var reg=/^\d[\s\S]*\d$/g;
        var str='123abc123';
        reg.test(str) -> true
 
 e.g.3 输入以下 replace 后的后果
        var str='aa'; //var reg=/a/;
        console.log(str.replace('a'/reg,'b'))
        后果为 ba(个别状况下只匹配到一个)var reg=/a/g;
        console.log(str.replace(reg,'b'))
        后果为 bb(全局匹配可匹配多个)e.g.4 把 aabb 转成 bbaa
        var reg=/(\w)\1(\w)\2/g;
        var str='aabb';
        console.log(str.replace(reg,'$2$2$1$1'));
        或:console.log(str.replace(reg,function($,$1,$2){return $2+$2+$1+$1}));
 
 e.g.5 把一串数字用迷信计数法示意(从右往左,每三个数打一个点)var str='10000000000';
        var reg=/(?=(\B)(\d{3})+$)/g;
        str.replace(str,'.');
 
详情可参考网址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
               或 https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp

一些杂碎

一旦经验了 var 的操作,所得出的 window 上的属性,这种属性叫做不可配置的属性,delete 不掉
undefined 和 null 不与数字比拟
typeof(arguments):object
document.documentElement 等于 html
在正则表达式中,加上? 可突破贪心匹配
正文完
 0