JavaScript 知识点

JS基础

  • 页面由三部分组成:
    • html:超文本标记语言,负责页面结构
    • css:层叠样式表,负责页面样式
    • js:轻量级的脚本语言,负责页面的动效和数据交互
      小总结:结构,样式和行为,三者相分离
    • 在html页面中写结构
    • 通过 link标签的href属性,引入css样式
    • 通过script标签的src属性,引入js脚本
  • css引入页面的方式有三种
    • 行内<div style="width:200px;height:300px;"></div>
    • 内嵌:在header里面写一个<style>选择器{key:value}</style>
    • 外链:在header里面写一个<link rel="stylesheet" href="css/index.css"/>
  • JS引入页面的方式,同CSS相似
    • 内嵌:在开发过程中,建议把script放在body底部;如果非要把script标签对,放在head里面的话;需要加window.onload
    window.onload=function(){
        document.body.innerHTML='XXXXXX';
    }
    
    • 行内:<div onclick="xxxx" onmouseover="xxxx"></div>
    • 外链:<script src="01.js"></script>
      注意:如果script作为JS的外链,一定不要在两个script标签中写代码,写了也没用
  • 属性和方法的区别:属性没括号,方法有括号
  • 字符串和变量的区别:字符串有引号,变量没引号
    • 字符串一般用单引号;为了元素身跟上的属性值区分开来;属性值一般是""
    • 变量,就是别名;var str; 告诉浏览器,定义了str这么一个变量
    • 如果没有定义变量,xxx is not defined
  • JS常见的输出方式7种
    • alert('') ; 显示带有一条指定消息和一个 OK 按钮的警告框
    • confirm('确定要删除?'); 他有两个返回值:true 真, false假
    • console.log(''); 可以在控制台打印出我们想要打印的内容
    • console.dir(); 打印出对象身上的属性和方法
    • document.write() 向文档写入 HTML 表达式或 JavaScript 代码
      如果遇到window.onload会清空页面
    • 元素.innerHTML=xxxx 设置或返回表格行的开始和结束标签之间的 HTML
    • console.table(); 可以把数组和对象,以表格的形式打印出来
    var ary2=[
        {
            name:'a',
            age:1,
            sex:'gril'
        },
        {
            name:'王b',
            age:2,
            sex:'boy'
        }
    ];
    console.table(ary2);
    
    
  • chrome控制台
    • Elements:用来调试html+css的
    • console:用来调试JS的
    • sources:可以拿到该网站相关的资源:images ,html ,css, js

体验JS编程思想

  • 需求:鼠标移入div1的时候,div2显示;鼠标移出div1的时候,div2隐藏

  • 实现思路:

    1. 高度:div2的高度为0; 移入div1后高度为100;移出div1时div2高度0;
    2. display:block显示,none,隐藏;
    3. 透明度:rgba(); opacity();
    4. 定位:left和top;
    5. margin:margin-left和 margin-top;
    6. overflow:hidden和visible;
  • JS获取元素的方式:

    • document.getElementById('id名字');
      因为id是唯一的,所以拿到的是一个元素
    • document.getElementsByTagName('标签名');
      标签名拿到的是一个元素集合;即使只有一个元素,也是个集合
      想要取到其中的一个:aDiv[0] aDiv[2]
  • JS中的数据类型

    • 基本数据类型:
      1. 字符串string
      2. 数字 number
      3. 布尔值 boolean
      4. undefined 现在没有,以后也没有
      5. null 空对象,现在没有,以后会有
    • 引用数据类型
      1. 对象数据类型
        • 数组
        • 正则
        • 对象{}
      2. 函数数据类型
        function 函数名(){};
  • 数据类型检测的方式

    1. typeof 可以检测基本数据类型(所有经过typeof的都是字符串),但是对于对象数据类型,检测出来的都是object,无法知道具体属于哪种对象
    2. 对象 instanceof 类; 比如ary instanceof Array 判断这个实例是否属于某个类
    3. 对象.constructor: 比如ary.constructor可以打印出对象所属的类
    4. Object.prototype.toString.call(ary); 出来的结果 '[object Array]'
  • 基本数据类型和引用数据类型的区别:

    • 基本数据类型:是对值的操作
    • 引用数据类型:是对地址的操作
  • 操作属性用的是"." oDiv.style.display='block'

  • 其他数据类型转为number数据类型

    • 强制转换
      • Number()
      • parseInt()
      • parseFloat()
    • 一个严格转换
      • Number()
    • 两个非严格转化
      • parseInt() 只能转化为整数
      • parseFloat() 可以保留小数

    如果转换失败的话,返回的结果是NaN:not a number 不是数字;但是NaN是number数据类型

  • 关于NaN:

    • NaN是number数据类型
    • isNaN() 判断是否为非有效数字; 非有效数字:true; 有效数字:false
  • 循环由4部分组成:

    • 1)定义 2)条件 3)语句 4)自增
  • 常见的循环方式:

    • for() :类数组arguments,htmlCollection,数组[],字符串
    • for in():普通对象{}
    • while(){}和for循环的区别和联系
      • 用while()循环也可以实现for循环的四步
      • for循环一般用在循环次数固定; while()循环次数不固定
    • do...while() 不管条件是否成立,都会先执行一次
  • 函数由两部分组成:

    • 函数定义3阶段
      • 开辟一个内存空间
      • 把函数体内所有的JS代码,作为字符串存在这个空间中
      • 把空间地址赋值给函数名
    • 函数调用2阶段
      • 当函数被调用的时候,会形成一个私有作用域
      • 把内存中的字符串作为JS代码来执行
        只定义不调用,函数不会执行
  • 闭包

    • 定义:
      • 当函数被调用的时候会形成一个私有作用域,保护里面的变量不受外界的干扰,函数的这种保护机制叫做闭包
      • 闭包就是在提供了一个在外部访问另一个函数内部局部变量的方式
var add = (function(){
    var count = 0;//外部访问的计数器,局部变量.
    var fun = function(){
        return ++count;
    }
    return fun;
})();
    
    //还可以这样写
    var add2 = (function(){
        var count = 0;//外部访问的计数器,局部变量.
        function plus(){
            return ++count;
    }
    return plus;
})();
    
//还可以这样写
var add3 = (function(){
    var count = 0;//外部访问的计数器,局部变量.
    return function(){
        return ++count;
    }
})();
  • 作用:
    • 避免全局变量名冲突
    • 在闭包中通过“window.xx”去修改全局变量;如果闭包中没有定义此变量,也可以直接修改变量去影响全局
    • 封装(闭包中封装的方法在全局不能使用,只能通过“window.xx=封装的函数名”把方法导出
    • 保存正确的i值
  • 特性:
    • 函数嵌套函数
    • 函数内部可以引用外部的参数和变量
    • 参数和变量不会被收回
  • 函数自带的参数机制叫做arguments;
    • arguments:能拿到实参,并且以类数组的形式展现; 类数组也是对象,是对象都有属性和方法
    • arguments.callee 拿到的是当前函数本身
    • arguments.length 拿到实参的长度/个数
  • 数字常用的方法:
    • toFixed(要保存的位数)四舍五入的保存小数位数的
  • 属性和方法的区别:
    • 属性没括号,方法有括号;方法本质就是对函数的调用
    • 对象的属性不会报错,如果没有,undefined; 方法不存在的话,会报错
    • 属性操作:. 和 []
      • 如果遇到变量,属性名[变量名] 注:千万不要给变量加引号
      • 如果遇到属性名为数字,属性名[1]
  • 参数有两种
    • 形参
      • 形参是私有变量
      • 如果定义了形参,但没有赋值,拿到是undefined
      • 形参个数不确定的话,用arguments来获取参数
    • 函数自带的参数机制arguments
      • arguments可以打印出实参,以类数组的形式打印出来
      • 0,1,2可以找到对应的属性值
      • arguments.callee;代表当前函数本身
      • arguments.length;打印出实参的个数
  • 函数返回值:
    • 函数返回值通过return;来返回
    • 获取值的时候,需要返回值;设置值的时候,不需要返回值
  • undefined出现的几种情况:
    • 属性:当对象的属性名不存在的话,拿到的是undefined
    • 参数:如果定义了形参,但是没有传实参,拿到的是undefined
    • 没有设置函数返回值,即没有写return,拿到的函数返回值为undefined
    • 写了return但没有赋值,拿到的函数返回值也是undefined
  • NaN出现的几种情况:
    • 转化失败时
    • 无效运算时:null+undefined、undefined+undefined
  • 运算符:
    • 算术运算符:+ - * / %
      • %(取余):技巧-有几种情况就%几
    • 比较运算符:
      > , >= , < , <= , == ,!= ,===, !==
    • 逻辑运算符:
      ! && ||
      • &&:两边都成立才能成立;但是也可以用它做条件判断; 9%3==0 && alert('能整除')
      • ||:一般成立就算成立;也可以用它做条件判断;9%3!=0 || alert('能整除')
    • 赋值运算符
      =; += ; -= ; *= ; /= ; %=
    • 运算符的优先级:算术》比较》逻辑》赋值
  • 条件判断:
    • if(条件1){....}else if(条件2){...}else{...}
    • 条件?语句1:语句2;
    • switch:用于多条件判断
    switch(判断的是可变的值){
        case a:
            语句1;
            break;
        case b:
            语句2;
            break;
        default:
            语句3;
            break;
    }
    
    每一种case情况其实都是相当于在用“===”进行比较
    • 如果只有一种条件,有三种写法:
      • if(条件){语句1}
      • 条件?语句1:null;
      • if(条件) 语句1;
      • 9%3==0 && alert('能整除');
      • 9%3!=0 || alert('能整除');

数组常用的方法

第一组:增加,删除和替换
  • push()
    • 作用:给数组末尾增加一项
    • 需要实参
    • 返回值:新数组的长度
    • 原数组发生改变
  • pop()
    • 作用:删除数组最后一项
    • 不需要参数
    • 返回值:被删除的内容
    • 原数组发生改变
  • unshift()
    • 作用:给数组开头增加一项
    • 需要实参
    • 返回值:新数组的长度
    • 原数组发生改变
  • shift()
    • 作用:删除数组第一项
    • 不需要参数
    • 返回值:被删除的内容
    • 原数组发生改变
  • splice()
    1. 插入/增加 splice(index,0,要添加的内容)
      • 作用:在指定的索引前面,插入我们要添加的内容
      • 参数:3个
      • 返回值:[]空数组,里面没有内容
      • 原数组发生改变
    2. 删除 splice(index,m)
      • 作用:从指定的索引地方开始,删除m个;如果第二个参数不写,就从索引一直删除到结尾
      • 参数:2个
      • 返回值:被删除的内容,以一个新数组的形式返回
      • 原数组发生改变
    3. 替换 splice(index,m,n)
      • 作用:从指定的索引开始,删除m个,并替换为n的新内容
      • 参数:3个
      • 返回值:被删除的内容,以一个新数组的形式返回
      • 原数组发生改变
第二组:克隆和截取/查找
  • slice(n,m)
    • 作用:从索引n开始,查找到索引m,包前不包后
    • 参数2个
    • 返回值:查找的内容
    • 原数组没有发生改变
    • 克隆的功能:slice(0)/slice()
      面试题:请找到数组中[n,m]项(答案:ary.slice(n-1,m))
  • concat()
    • 作用:数组拼接 / 克隆ary.concat()
    • 参数:不确定,想拼接几个数组,里面参数就写几个数组名,也可以写成数组的形式
    • 返回值:拼接成的新数组
    • 原数组没有发生改变
第三组:数组转字符串
  • toString()
    • 作用:数组转字符串
    • 参数:无
    • 返回值:以逗号分割的新字符串
    • 原数组没有发生改变
  • join(拼接形式) 拼接形式可以为任何运算符号
    • 作用:数组转字符串
    • 参数:拼接形式可以为任何运算符号
    • 返回值:以指定的拼接形式分割的新字符串
    • 原数组没有发生改变
    • 如果拼接形式为+之类的,想实现运算,可以用eval()
    • eval():把字符串作为JS代码来执行
第四组:数组的翻转和排序
  • 数组翻转 ary.reverse()
    • 功能:数组翻转
    • 参数:没有
    • 返回值:被翻转后的数组
    • 原数组发生改变
  • 数组排序
ary.sort(function(a,b){
    return a-b;//从小到大排; return b-a 从大到小排
})
第五组:数组常用但不兼容的方法
  • indexOf()
    • 功能:查找内容
    • 参数:要查找的内容
    • 返回值:如果找到,返回内容对应的索引/位置; 如果没找到,返回-1
    • 原数组不变
  • forEach():遍历数组的
    • 作用:遍历数组的
    • 参数有两个:1)callback 2)context:改变this指向的
    • callback中有三个参数:item,index,input
    • 返回值:undefined; 没有返回值
    • 原数组不变
  • map():也是遍历数组,跟forEach()功能一样,只是forEach()没有返回值;map有返回值

Math常用的方法

  • Math.round() 四舍五入
  • Math.floor() 向下取整
  • Math.ceil() 向上取整
  • Math.abs() 绝对值
  • Math.sqrt() 开平发
  • Math.pow() 幂次方
  • Math.max() 最大值
  • Math.min() 最小值
    求n-m之间的随机整数:Math.round(Math.random()(m-n)+n);

字符串常用的方法:

  • 通过下标找对应的字符
    • charAt() 返回指定位置的字符
    • charCodeAt() 返回在指定的位置的字符的 Unicode 编码
  • 通过字符找下标
    • 从前往后找:indexOf()
    • 从后往前找:lastIndexOf()
  • 字符串截取
    • slice(n,m) 从索引n截取到索引m;不包含m;包前不包后;但是,slice可以取负值
    • substr(n,m) 从索引n开始,截取m个
    • substring(n,m) 从索引n截取到索引m;不包含m
  • 字符串转数组
    • split(切割形式:字符串或正则表达式) 把字符串分割为字符串数组,返回一个字符串数组
  • 转大小写
    • toUpperCase() 把字符串转换为大写
    • toLowerCase() 把字符串转换为小写
  • 跟正则配合的字符串方法
    • split() 把一个字符串分割成字符串数组
    • match() 检查一个字符串是否匹配一个正则表达式
    • replace('a','b') 把a替换为b;替换与正则表达式匹配的子串
    • search() 检索与正则表达式相匹配的值;找到的情况下,返回对应内容的索引;找不到的返回-1
  • 其他数据类型转为number数据类型
    • 一个严格转换Number(),两个非严格转换parseInt() parseFloat()
    • 转换失败是NaN
    • [] 默认通过 toString() 转成空字符串; Number("")===0
    • null默认转为0;null+10=10; undefined+10=NaN
    • false===0; true===1
  • 其他数据类型转为布尔数据类型
    • Boolean()
      • 假:"",0,NaN,null,undefined,false
      • 真:除了假都是真
    • if(一个值) 会转成布尔
    • if(表达式/比较) 会默认转成布尔
    • !
  • 其他数据类型转成字符串数据类型
    • 对象转字符串:toString()
    • 数字转字符串:""+数字
  • 数据类型的比较:
    • 对象==对象 比较的是地址 []==[] false
    • 字符串==对象 转成字符串 ""==[] true
    • 字符串==数字 转成数字 ""==0 true
    • 字符串==布尔值 转成数字 ""==![] true
    • 数字==对象 转成数字 0==[]
    • 布尔值==对象 转成数字 false==[] ![]==[]
    • 数字==布尔值 转成数字 false==![]
    • null==undefined true
    • null===undefined false
    • NaN==NaN false ;NaN跟任何值都不相等,包括自己也不相等
  • 给数组末尾增加一项
    • push()
    • ary[ary.length]=xxx;
    • ary.splice(ary.length,0,xxxx);
  • 删除数组最后一项
    • pop()
    • ary.length--; ary.length-=1; ary.length=ary.length-1;
    • ary.splice(ary.length-1,1);
  • 如何实现克隆
    • ary.slice();/ary.slice(0)
    • ary.concat();
    • ary.splice(0) 注意:如果用splice()进行克隆,0不能省略
    • for循环也可以实现;但for循环是循环,不是方法
  • 定时器
    • 隔一段时间爆发一次:
      • setInterval(callback,毫秒数);
      • 关闭定时器 clearInterval(定时器的名字)
    • 只爆发一次:
      • setTimeout(callback,毫秒数);
      • 关闭定时器 clearTimeout(定时器的名字)
  • n++ 和 ++n的区别
    • ++n 先++,再运算;累加后的结果参与了运算
    • n++ 先运算,再++; 累加后的结果不参与运算
  • 创建数组的两种方式
    • var ary=[1,2,3]; 字面量方式创建
    • var ary2=new Array(1,2,3); 实例创建

  • DOM树:由一大堆的元素和标签组成;所以DOM就是用来操作页面中的标签的
  • DOM中的获取方式有以下几种:
    • id
    • className
    • tagName
    • name
    • 可视区的宽度:document.documentElement.clientWidth||document.body.clientWidth;
    • 可视区的高度:document.documentElement.clientHeight||document.body.clientHeight;
    • querySelector() #id .class div 拿到的是一个元素
    • querySelectorAll() #id .class div 拿到的是一组元素
  • 节点:
节点类型 说明
元素节点 每一个HTML标签都是一个元素节点(例如:<div>、<input>等) 1
属性节点 元素节点(HTML标签)的属性(例如:id 、class 、name 等) 2
文本节点 元素节点或属性节点中的文本内容 3
注释节点 表示文档注释,形式为 8
文档节点 表示整个文档(DOM 树的根节点,即 document ) 9
  • DOM动态操作

    • 创建新标签
      • document.createElement(标签名) 创建
      • 克隆 obj.cloneNode(false/true);//false:只克隆表面; true:深度克隆
    • 动态插入
      • 父级.appendChild(新元素) 插入到父容器的末尾
      • 父级.insertBefore(newEle,oldEle) 插入到指定元素的前面
    • 删除标签
      • 父级.removeChild(获取到的元素名)
  • 属性操作

    • . 和 []
    • attribute
      • setAttribute(属性名,属性值) 设置属性
      • getAttribute(属性名) 获取属性
      • removeAttribute(属性名) 移除属性
    • 1)通过点来设置自定义属性,看不到;但是通过setAttribute()可以看到;
      2)通过点获取元素身上已经定义好的的自定义属性,获取不到;但是通过getAttribute()可以拿到;
      注意:用"."都用点,用attribute,都用attribute;千万不要混搭!
  • 判断属性是否存在的方法

    • in: "属性名" in 对象 如果支持,返回true;不支持返回false
    • ".": 对象.属性名 如果不支持,返回undefined
  • 预解释:当前作用域下,在JS代码执行之前浏览器会对带var和带function的进行提前声明或定义

  • 带var和带function的声明和定义不同:

    • 带var的,只声明不定义
    • 带function,声明+定义
  • 函数定义三步骤:

    1. 开辟一个空间地址
    2. 把函数体内所有JS代码作为字符串放在这个空间中
    3. 把空间地址赋值给函数名=
  • 函数调用四步骤:

    1. 形成一个私有作用域
    2. 形参赋值
    3. 预解释
    4. 代码从上到下的执行
  • 上级作用域
    上级作用域跟函数在哪里调用无关,只跟函数对应的堆内存在哪里开辟有关

  • 作用域链

    1. 当函数被调用的时候,会形成一个私有作用域;在这个作用域中查找是否有私有变量a
    2. 如果有私有变量a:那么整个函数体内的所有a都是私有变量,跟外界没有任何关系
    3. 如果没有私有变量a:去上级作用域找,找不到,继续往上级找,如果找到window还没有的话,报错!
  • 私有变量主要有两种

    • 函数体内带var的
    • 形参

  • 内存包含:堆内存和栈内存
  • 堆内存:用来存放数据
    • 对象数据类型的
      • 存的是键值对 key=value
    • 函数数据类型的
      • 代码字符串
  • 堆内存的释放:
    var a=[1,2,3,4]
    释放:a=null
  • 栈内存:本身提供了一个供JS代码执行的环境
    • 包含:全局作用域 和 私有作用域
  • 全局作用域的形成和销毁:
    • 形成:当一个页面被浏览器加载完成的时候,全局作用域就形成了
    • 销毁:1)关闭页面 2)关闭浏览器
  • 私有作用域的形成和销毁:
    • 形成:当函数被调用的时候,会形成私有作用域
    • 销毁:一般情况下,当函数执行完成的时候,默认就被销毁了;但是两种情况下不销毁:
      • 不销毁:当函数体内的东西被外面的变量或者其他占用的话,就不销毁
      • 不立即销毁:当函数执行完成的时候,会返回一个函数,被返回的函数还需要再执行一次;只有所有的调用都完成的时候,这个函数才能销毁

  • 预解释无节操
    • 只对等号左边带var的,声明但不定义
    • 自执行函数不会进行预解释,只有,执行到他的时候,声明+定义+调用同步完成
    • 已经声明过的不会进行重复声明,但会重新赋值
    • return下面的语句虽然不会执行,但会进行预解释
    • 函数的声明早于变量的声明
    • (在IE10及10以下浏览器下)在条件判断语句中,无论条件是否成立,都会进行预解释
      不要在条件判断语句中写函数的定义阶段;否则,各大浏览器对其的兼容性不同

全局变量,都是window的全局属性;
全局函数,都是window的全局方法。
比如:

  setInterval()
  setTimeout()
  alert()
  confirm()

  • 关于this
    • 当一个元素身上的事件被触发的时候,会执行一个函数,函数中的this指向当前这个元素
    • 自执行函数中的this,永远都是window
    • 回调函数中的this,一般都是window
      setInterval(函数名,1000) ; ary.sort(function(){}) ;
    • 当函数被调用的时候,看前面是否有".","."前面是谁,this就是谁
    • 当遇到call、apply、bind时,以上规律失效;因为他们可以改变this指向
    • 箭头函数中的this指向父函数中的this

  • 改变this指向的函数:
    • call(arg1,arg2,arg3,arg4......)
      • call的一个参数用来改变call前面的函数中的this关键字
      • call从第二个参数开始,相当于给call前面的函数从左往右一个个的赋值;
      • call当改完this指向,传完参数后,立即执行了
    • apply(arg1,arg2) arg2可传可不传
      • arg1用来改变this指向,具体跟call一样
      • 区别:apply的第二个参数是个数组,存放所有需要给形参的值;
        虽然apply的第二个参数是个数组,但是对于形参来说,也是从左往右一个个的赋值
    • bind(预处理机制)
      • bind的传参形式跟call一样
      • 注:bind属于预处理机制,当调用bind的时候,会返回一个已经改好this,传好参数的函数,你只需要在需要的时候,调用即可

  • 带var和不带var的区别:
    • 带var:
      1)会进行预解释
      2)如果在全局作用域下,他就是window的全局属性
    • 不带var:
      1)不会进行预解释
      2)不带var在"赋值"的时候,相当于window添加全局属性

面向对象

  • 对象两大特征:属性 和 方法

  • 面向对象(oop,oo)思想的特点:

    • 封装:对于同一个功能,只需要封装一次,以后再使用的时候,只需要调用即可,无需重写;低耦合高内聚
    • 继承:子类可以继承父类的属性和方法
    • 多态:重载 和 重写
      • 重载:JS上没有严格意义上的重载;但有类似重载的功能,就是传不同的参数,有不同的返回值
      • 重写:子类可以重写父类的属性和方法
  • 面向对象的四种常见设计模式:

    • 单例模式
      • 把同一个对象上的属性和方法,都放在同一个命名空间
      • 单例模式的本质:普通对象
      • 模块化开发:对于一个复杂的大项目,可以分配给不同的工程师同步进行开发;等项目完成的时候,合并即可
        • 各个模块之间的相互调用:对象名.属性名
        • 本模块之间的相互调用:this.属性名
          ** 缺点:造成大量冗余代码**
    • 工厂模式
      • 工厂模式有3步:
        • 引进原材料 创建一个空对象{}
        • 加工原材料 加工对象:给对象添加属性和方法
        • 输出产品成 输出对象: return
      • 工厂模式,为了让他长的像系统的类 new Array()
      • 工厂模式和构造函数模式的区别:
        1. 在调用的时候:
          工厂模式 person()
          构造函数模式 new Person()
        2. 在函数体内
          工厂模式三步:1)创建对象 2)给对象添加属性和方法 3)返回对象
          构造函数模式只有一步:2)给对象添加属性和方法 ; 第一步和第三步系统帮做了,系统提供了一个对象叫this
    • 构造函数模式
      1.构造函数首字母一定大写
      2.构造函数中放的都是私有的属性和方法
      3.原型上放的都是公有的属性和方法
      4.系统默认会创建一个对象,this
      5.系统默认会返回一个对象 this
      6.构造函数中的this,指向当前这个实例(构造函数new给谁,this就指向谁)
    • 原型模式
      • 原型模式基础:
        1. 每个函数数据类型(普通函数,类),都有一个属性,叫做prototye,prototype是个对象
        2. prototype这个对象上,天生自带一个属性,叫做constructor,指向当前所属类
        3. 每个对象(普通对象,实例,prototype)身上,都有一个属性,叫做__proto__,指向当前对象所属类的原型
      • 原型链:__proto__
        如果要查找 对象.属性名 比如f1.showX
        1. 先在自己的私有作用域中查找;如果找到,那么这个属性是私有属性
        2. 如果没找到,到当前实例所属类的原型上找(f1.__proto__),如果找到属于公有的属性或方法
        3. 如果没找到,继续通过__proto__往上找,一直找到Object.prototype上还没有的话,undefined
      • 要形成的几个条件反射:
        1. 一看到构造函数:存的都是私有的属性和方法
        2. 一看到prototype:存的都是公有的属性和方法
        3. __proto__原型链
  • 两大boss:Object 和Function
    1 Function 是 Object 的爹
    2 Object 是 Function 的爹
    3 Object 是 Function.prototype的爹
    4 Object.prototype 是 Function.prototype的爹

  • 函数的三种角色:

    • 普通函数:形成一个私有作用域,形参赋值,预解释,代码执行,内存和内存释放,作用域链
    • 类:实例,prototype,constructor,类,原型链__proto__
    • 普通对象:具有普通对象的特征:属性和方法
  • 如果给原型自定义了一个对象,那么自定义的这个对象上,没有constructor

  • 属性判断

    • in:判断某个属性是否在元素上(包含了私有+公有)
    • hasOwnProperty判断某个属性是否为元素身上的私有属性
      使用 obj.hasOwnProperty(属性名)
    • 写一个方法:判断是否为公有属性
      • isPrototypeOf:判断前一个对象是否在后一个对象的原型链上;返回的布尔值
      • propertyIsEnumerable:他的作用跟hasOwnProperty类似;返回的布尔值
  • 继承:子类继承父类的属性和方法

    • call继承:子类只继承父类私有的属性和方法;父类私有的属性和方法,都在父类的构造函数里
    • 拷贝继承:私有通过call来继承,公有通过extend() 来继承
    • 原型继承:
      • 私有继承:call继承
      • 公有继承:父类原型上的属性和方法,只有父类中的实例可以使用
      • 子类原型可以使用父类原型上的属性和方法;子类原型作为父类的实例

  • 类数组转数组
    • 类数组有两种:
      1. arguments
      2. htmlCollection 元素集合
    • 浏览器异常捕获
      try....catch(e){}...finally{..}
      平常用的,只有 try...catch...
      使用场景:只要有报错的情况,建议用try...catch....
    • JSON: JOSN 是系统window的属性
      • JSON.parse() 把JSON格式的字符串,转成JSON格式的对象
      • JSON.stringify() 把JSON格式的对象,转成JSON格式的字符串
        注意JSON,属性名一定是双引号"";属性值,如果是数字,可以没有引号
    • eval() 容易引起"注入攻击"

  • sort排序
    • DOM映射:html页面中的DOM结构,跟通过JS获取到的元素集合htmlCollection之间,存在一一对应的关系
      • appendChild() 有类似剪切的功能
    • sort排序三步骤:
      1 类数组转数组
      2 sort排序
      3 把排好序的内容,重新插入页面
    • 把数据插入页面的几种方式
      1. 字符串拼接; _插入页面用innerHTML
      2. 动态创建和插入; document.createElement() 父级.appendChild(元素)
      3. 文档碎片:
        1)先把创建好的每个元素,放入文档碎片
        2)最后把文档碎片放入父元素中
        3)释放文档碎片

  • 前端往后台的请求方式:
    1. GET 请求数据
    2. POST 发送数据
    3. DELETE 删除数据
    4. PUT 提交数据
  • 同步和异步:
    • 同步:每次只能完成一个任务,必须等这个任务完成之后,才能开始下个任务
    • 异步:当前的任务没完成,不用等待,继续开始下个任务,也就是,可以多个任务并行
      • 回调异步
      • 事件
      • 定时器
      • ajax
  • http响应状态码
    • 2xx 成功
    • 3xx 重定向
    • 4xx 请求错误
      • 400 请求的参数错误
      • 404 文件没找到
    • 5XX 服务器错误

  • 正则(手册:http://tool.oschina.net/uploads/apidocs/jquery/regexp.html)

    • 作用:玩字符串的
    • 定义:通过制定一系列的规则来操作(校验/匹配、捕获)字符串
      • 校验: reg.test() ;/^2\d{2}/.test(xml.status);
      • 捕获:1)str.match(reg) 2)reg.exec(str); 3)str.replace(reg);
        正则的方法: reg.test() reg.exec()
        字符串的方法:str.match() str.replace() str.split() str.search();
  • 创建正则的方式:

    • var reg=/^2\d{2}/; 字面量的创建方式
    • var reg=new RegExp(); 实例创建
  • 字面量创建和实例创建的区别:

    1. 字面量创建无法拼接变量,实例创建可以拼接变量
    2. 字面量创建不需要转义,实例创建需要转义
  • 正则由元字符和修饰符两部分构成: var reg=/^2\d{2}/g;

    • 元字符:就是包含在两个斜杠之间,陌生的字符
    • 修饰符:就是斜杠外面的
  • 元子符包含:特殊含义的元字符和量词元字符

    • 特殊含义的元字符:
      \ 转义
      | 或
      () 分组
      . 除了\n以外的其他字符
      \n 换行
      \b 开头结尾和空格
      ^ 开头
      $ 结尾
      \s 空格 \d 数字 \w 数字,字母,下划线
      \S 非空格 \D 非数字 \W 非数字,非字母,非下划线
      [a-z] 任意一个小写字母
      [^a-z] 除了字母以外的任何一个字符
      [abc] “a,b,c”中的任意一个字母
      [^abc] 除了“a,b,c”以外的任意一个字母
    • 量词元字符
      • * 重复0次或多次
      • + 重复1次或多次
      • 0 或1,可有可无
      • {n} 正好n次
      • {n,} 最少n次;n次到多次
      • {n,m} n次到m次
  • 修饰符:

    • g 全局
    • m 换行
    • i 忽略大小写;ignore
  • ()小括号的用法:

    1. 提高优先级 /^(18|19)$/
    2. 分组的作用
  • []中括号的用法:

    1. 中括号中不会出现两位数
    2. 像类似于.-之类的,在中括号中都没有特殊函数
  • ?问号的作用:

    1. 可有可无
    2. 解决正则捕获的贪婪性
  • 捕获

    • 正则中的捕获,主要讲三点:
      • exec: reg.exec(str);
      • match: str.exec(reg);
      • replace:str.replace(reg,xxxxxx)
    • 正则捕获有两大特点:
      1. 懒惰性:
        • 解决措施:添加全局g
        • 加了全局g,会影响lastIndex(从你找到内容 的 下一项内容的 索引 开始查找)
      2. 贪婪性:
        • 解决措施:在量词元字符后面加上?
    • exec,是正则的方法,每次只能拿到一个值;返回的结果是个数组,默认情况下,数组有3项:
    1. 符合大正则的内容
    2. index:找到的内容所对应的索引;(位置)
    3. input:原始字符串;
      如果有小分组的情况下,小分组从数组的第二项开始;数组的长度也会因为小分组而增加
    • match:是字符串的方法,每次能到所有符合正则的内容,并且以一个新数组的形式返回
    • exec和match的区别:
      1. exec每次只能拿到一个值;match能拿到所有值,并以新数组的形式返回
      2. exec能拿到小分组; match只能拿到大正则,无法拿到小分组
  • replace

    • replace中的回调函数,默认接收三个参数,如果有小分组,arguments的长度会扩充
    • replace回调函数中第一个参数的运用:敏感词过滤
    • replace回调函数中第2个参数的运用:把数字作为数组的索引,找到对应的值
  • 统计出现次数最多的单词
    思路1:
    1) 利用对象不重名的特性
    2) 假设法
    3) 字符串拼接
    思路2:
    1)字符串排序:字符串转数组-数组排序-数组转字符串
    2)假设法+重复子项 /(\w)\1+/gi;

  • 解析URL地址: /([&?=]+)=([&?=]+)/g;

  • 日期格式化:
    重点,字符串转成数组,三种思路:
    1)严格匹配;

var reg=/^(\d{4})[/-](\d{2})[/-](\d{2}) (\d{2}):(\d{2}):(\d{2})$/;
    var ary=null;
    str.replace(reg,function(){
        ary=Array.prototype.slice.call(arguments,1,arguments.length-2)
    });
  1. split 切
    var ary=str.split(/[^\d]+/g);
  2. match 捕获
    var ary=str.match(/\d+/g);
  • ?的用法
    1) 0或1
    2) 解决正则捕获的贪婪性 +?
    3) 只匹配不捕获 (?:\d+)
  • 小括号的用法:
    1)分组
    2)提高优先级
    3)只匹配不捕获 (?:\d+)
  • var reg=new RegExp();
  • 在有全局g的情况下,能影响lastIndex的值的属性有两个:
    1)reg.test()
    1. reg.exec()
  • 回调函数需要注意的几点:
    1. 回调函数被调用的次数;比如,map中回调函数被调用的次数,取决于数组的长度
    2. 回调函数是否需要传参;比如,map中回调函数接收三个参数
    1. item
    2. index
    3. input
  1. 回调函数中this默认指向window,可以通过call来改变this指向
  2. 回调函数是否有返回值;比如 forEach()没有返回值; map()有返回值,他是把每个回调函数的返回值保存在一个数组中,最后返回出map
  • CSS盒子模型
    • 构成:手动设置的宽高+padding+border+margin
  • JS盒子模型
    • 主要通过元素身上提供的属性和方法,来获取元素身上的样式值
  • JS中盒子模型所设计的属性和方法,主要包含以下几类:
    1. client系列:clientWidth clientHeight clientLeft clientTop
    • clientWidth/clientHeight: 手动设定的宽度/高度+左右/上下padding
    • clientLeft/clientTop: 左边框的宽度 / 上边框的宽度
    1. offset系列:offsetWidth offsetHeight offsetLeft offsetTop offsetParent
    • offsetWidth/offsetHeight:手动设定的宽度/高度+左右/上下padding+左右/上下的border宽度
      (clientWidth+左右border clientHeight+上下border)
    • offsetLeft/offsetTop:当前元素的外边框距离他定位父级的内边框之间的距离
    • offsetParent: 定位上的父级
  1. scroll系列:scrollWidth scrollHeight scrollLeft scrollTop
  • scrollWidth/scrollHeight:
    • 在内容没有溢出的情况下,
      scrollWidth/scrollHeight等于clientWidth/clientHeight;
    • 如果内容溢出的情况下,
      scrollHeight约等于上padding+真实内容的高度
      为什么是约等于:
      1)当内容溢出的情况下,不同浏览器拿到的值不同
      2)同一浏览器下,内容是否溢出拿到的值也不同
  • scrollTop:指当前页面被浏览器卷去高度
  • JS盒子模型遇到的问题
    1. JS盒子模型中求出来的都是四舍五入的整数,无法拿到小数 --不解决
    2. JS盒子模型中拿到的值都是复合值,无法拿到单独的宽或高; --解决:封装getCss
    3. 关于盒子模型的偏移量,我们只能求出当前容器的外边框到定位父级的那边框之间的距离,无法求出当前定位元素到body的距离;--解决:封装offset
    4. 求可视区的宽高或被浏览器卷去的高度和宽度,太麻烦了;-- 封装win

  • 箭头函数
    • 表达式
      1. var fn=p=>p;
      2. var fn=()=>'我没有参数';
      3. var fn=(n,m)=>n+m;
    • 函数体
      1. var fn=p=>{return p};
      2. var fn=()=>{return '我没有参数'};
      3. var fn=(n,m)=>{return n+m}
        注:箭头函数中的this,指向父函数的this
  • 类的创建和继承
    • 类的创建
class 类名{
    constructor(){//写私有的属性和方法
    }
    getName(){//公有的属性和方法
    }
    static getAge(){//类的静态方法;也是类的私有方法,实例不能使用
    }
}
类.xxxx=xxxx;//类的私有属性
  • 类的继承
class S extends F{
    constructor(name,age,color){
        super(name,age);
        this.color=color;
    }
    //下面正常写子类公有的
}
  • 解构赋值:{属性名}=persion;//实际拿到的是对象身上该属性名对应的值
  • let 和 const
    1. 他两都不能进行预解释
    2. let会形成块级作用域
    3. const 是个常量,不能进行更改

  • $(document).ready() 和 window.onload的区别:
    • window.onload 是等页面所有的内容(图片,音频,视频,DOM结构.....)都加载完成的时候,才执行JS代码
    • $(document).ready(function(){...代码}) 只要DOM结构加载完成,就开始执行JS 代码

  • jQuery选择器
    • 基本选择器:
      ('#div')('.div') ('div')('.div1,.div2');
  • JS和jquery只能共存,不能混淆
    • JS 转成jquery:只需要被包裹即可;(this) $(oDiv)
    • jquery转JS: [index] get(index)
  • jquery中DOM常用方法
    • append 和 appendTo
      联系:功能相同,但是针对的主体不同
    • 创建元素 ('
      ')('<div></div>')

  • 运动

    • show() 显示隐藏的元素
      hide() 隐藏显示的元素
    • slideDown() 通过使用滑动效果,显示隐藏的被选元素
      slideUp() 通过使用滑动效果,隐藏被选元素,如果元素已显示出来的话
    • fadeIn() 使用淡入效果来显示一个隐藏的元素
      fadeOut() 使用淡出效果来隐藏一个元素
    • animate(target,time,effect,callback) 执行 CSS 属性集的自定义动画
      stop() 停止当前正在运行的动画
  • ajax前后端数据交互

ajax({
     type:'get/post',
     url:'xxxx?'+Math.random()*1000000+new Date().getTime(),
     async:true/false,
     dataType:'json',//解决了jsonParse()
     data:$('form').serialize()//表单序列化:就是把前端要传后台的数据,以k=v&k=v拼成字符串
     success:function(){//成功之后的回调
     },
     error:function(){//失败之后的回调
     }
})

  • 事件和事件绑定
    • 事件绑定:2个
      on(type,fn) //可以执行多次
      one(type,fn) //只能执行一次
    • 解除绑定
      off(type,fn);//注意:只能解除有名字的函数

  • each和map
    • ().each() 和.each()的区别:
      • $().each() 只能遍历jquery获取到的元素
      • $.each() 既可以遍历jquery元素也可以遍历原生数组和原生对象
    • ().map() 和.map() 他们 与 each的区别
      • map的回调函数接收的参数,跟each的顺序正好相反
      • map可以返回一个新的数组;而each拿到的还是原来的数组

  • 事件
    • 鼠标事件:
      onclick ondbclick onmouseover onmouseout onmouseenter onmouseleave
    • 系统事件:
      onload resize onscroll
    • 键盘事件:
      onkeydown onkeyup onkeypress
    • 表单事件:
      onfocus onblur autofocus=true/false;
  • 事件分类:DOM0级事件 和 DOM2级事件
    • DOM0级事件 和 DOM2级事件的区别:
      1. DOM0级事件:
        1)在元素的私有属性上
        2)同一个元素,同一个行为,只能绑定同一个方法;如果多次绑定,后面的方法会覆盖前面的方法
        3)只能发生在事件流的冒泡阶段
      2. DOM2级事件:
        1)在元素所属的EventTarget这个类的原型上
        2)同一个元素,同一个行为,可以绑定多个不同的方法
        3)可以人为的控制发生事件流的哪个阶段(捕获,冒泡)

  • 标准浏览器下:
    addEventListener(type,fn,useCapture);

    • 解绑:
      removeEventListener(type,fn,useCapture);
      注意:所有的行为,都不加on
  • IE6-8下:
    attachEvent('on'+type,fn)

    • 解绑:
      detachEvent('on'+type,fn);
      attachEvent只能发生在冒泡阶段

  • 事件流
    • 由三部分构成:捕获,target事件源,冒泡
    • 由两部分构成:捕获,冒泡
      注意顺序:先捕获,后冒泡
  • 一个元素的层级嵌套:
    元素自己->HTMLDivElement ->HTMLElement->Element->Node->EventTarget->Object
  • 事件对象
    • 事件对象的兼容处理:e=e||window.event
    • 事件源:e.target=e.target||e.srcElement;
    • 坐标:距离当前可视区左上角的坐标-兼容:e.clientX; e.clientY;
    • 坐标:距离第一屏左上角的坐标:e.pageX;e.pageY;
      不兼容:
      e.pageY=(document.documentElement.scrollTop||document.body.scrollTop)+ e.clientY;
      e.pageX=(document.documentElement.scrollLeft||document.body.scrollLeft)+ e.clientX;
    • 事件类型:e.type
    • 键码:e.keyCode
    • 阻止默认事件: e.preventDefault?e.preventDefault():e.returnValue=false;
    • 阻止冒泡 e.stopPropagation? e.stopPropagation():e.cancelBubble=true;
  • 熟悉标准浏览器中的DOM2级事件绑定
    • addEventListener特点:(标准浏览器)
      1. 按"绑定的"先后循序执行的
      2. this指向当前被绑定事件的这个"元素"
      3. 如果给同一个元素,同一个行为绑定多次同一个方法,实际上只执行一次
    • attachEvent的问题:
      1. 顺序不对
      2. this不对,attachEvent中的this,默认指向window
      3. 如果给同一个元素,同一个行为绑定多次同一个方法,执行的是多次;也不对

补充

  • null和undefined区别:

    1. 定义变量时:null现在没有,以后会有;undefined:现在没有,以后也没有
    2. null转为数值为0,undefined转为数值为NaN
    3. 报错时:undefined表示“缺少值”,即 此处应该有一个值,但没定义;null表示“没有对象”,即 此处不该有值
  • 性能优化

    • 网页内容
      • 减少 http请求次数
      • 减少 DNS查询次数
      • 避免页面跳转
      • 缓存 Ajax
      • 延迟加载
      • 提前加载
      • 减少 DOM元素数量
      • 避免 404
    • 服务器
      • 使用CDN(内容分发网络)
      • 添加Expires或Cache-Control报文头
      • Gzip压缩传输文件
    • CSS
      • 将样式表置顶
      • 用代替@import
    • JavaScript
      • 把脚本置于页面底部
      • 使用外部JavaScript和CSS
      • 精简JavaScript和CSS
      • 去除重复脚本
      • 减少DOM访问
    • 图片
      • 优化图像
      • 优化CSS Spirite
      • 不要在HTML中缩放图片
      • favicon.ico要小而且可缓存
  • 如何解决跨域问题
    jsonp 原理:动态插入script标签

  • JavaScript同源策略
    这里的同源策略指的是:协议,域名,端口相同。同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

  • 哪些操作会造成内存泄漏?
    1、内存泄漏指任何对象在您不再拥有或需要它之后仍然存在
    2、垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),那么该对象的内存即可回收
    3、setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)

  • 事件代理(Event Delegation) 即 事件委托

  • 定义:把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务

  • 原理:DOM元素的事件冒泡

  • 优点:提高性能

上一篇:GitLab 常用方法


下一篇:div 居中方法汇总