欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript 知识点

程序员文章站 2024-01-30 16:22:28
...

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元素的事件冒泡

  • 优点:提高性能