JavaScript部分要点总结
文章目录
一、闭包
1.什么是闭包?
闭包就是函数嵌套函数,内部函数可以访问外部函数中的变量,当内部函数被当作返回值并在外部调用是就会产生闭包。
2.闭包的作用
- 闭包最大的作用就是隐藏变量,闭包的一大特性就是内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回了之后。
- 基于此特性,JavaScript可以实现私有变量、特权变量、储存变量等
3.闭包的优点
- 可以隔离作用域,不造成全局污染
4.闭包缺点
- 由于闭包长期驻留内存中,则长期这样会导致内存泄漏
- 对捕获的数据是引用不是复制
5.适用场景
封装组件,for循环和定时器结合使用,for循环和dom事件结合.可以在性能优化的过程中,节流防抖函数的使用,导航栏获取下标的使用
二、原型链
原型链是理解JS面向对象很重要的一点,这里主要涉及到两个点,一是_ proto ,二是prototype,举个例子吧,这样还好说点,例如:我用function创建一个Person类,然后用new Person创建一个对象的实例假如叫p1吧,在Person类的原型 prototype添加一个方法,例如:play方法,那对象实例p1如何查找到play这个方法呢,有一个查找过程,具体流程是这样的:
首先在p1对象实例上查找是否有有play方法,如果有则调用执行,如果没有则用p1.proto(_proto_是一个指向的作用,指向上一层的原型)往创建p1的类的原型上查找,也就是说往Person.prototype上查找,如果在Person.prototype找到play方法则执行,否则继续往上查找,则用Person.prototye.__proto__继续往上查找,找到Object.prototype,如果Object.prototype有play方法则执行之,否则用Object.prototype.__proto__继续再往上查找,但Object.prototpye.__proto__上一级是null,也就是原型链的顶级,结束原型链的查找,这是我对原型链的理解
三、js继承
1.ES5实现继承主要是基于prototype来实现的,具体有三种方法
一是原型链继承:即 B.prototype=new A()
二是借用构造函数继承(call或者apply的方式继承)
function B(name,age) {
A.call(ths,name,age)
}
三是组合继承
组合继承是结合第一种和第二种方式
2.ES6继承是目前比较新,并且主流的继承方式,用class定义类,用extends继承类,用super()表示父类。
//例如:创建A类
class A {
constructor() {
//构造器代码,new时自动执行
}
方法1( ) { //A类的方法 }
方法2( ) { //A类的方法 }
}
//创建B类并继承A类
class B extends A {
constructor() {
super() //表示父类
}
}
/*实例化B类:*/ var b1=new B( )
b1.方法1( )
四、js原生事件如何绑定
JS原生绑定事件主要为三种:
- html事件处理程序
- DOM0级事件处理程序
- DOM2级事件处理程序
第一种html事件现在已经不用了,就是直接在html标签上添加事件,缺点是不好维护,耦合度高。
<div onclick="事件处理函数">按钮</div>
第二种是DOM0级事件,他主要就是在js中先获取dom元素,然后给dom元素添加事件
var btn=document.getElementById('id元素')
btn.onclick=function() {
//要处理的事件逻辑
}
移出dom事件:btn.οnclick=null;事件等于空就行。
优点:兼容性好
缺点:只只吃冒泡,不支持捕获
第三种是DOM2级事件,它也是在js中先获取dom元素,但是它给添加和移除事件都提供了方法。
//绑定事件
btn.addEventListener(‘click’,绑定的事件处理函数名,false)
//移除事件
btn.removeEventListener(‘click’,要移除的事件处理函数名,false)
优点:支持给个元素绑定多个相同事件,支持冒泡和捕获事件机制
五、js原生常用dom操作方法
1.查找:
- getElementByid
- getElementsByTagName
- querySelector
- querySelectorAll
2.插入
- appendChild
- insertBefore
3.删除
- removeChild
4.克隆
- cloneNode
5.设置和获取属性:
- setAttribute(“属性名”,”值”)
- getAttibute(“属性名”)
六、ES6新特性
- 新增了块级作用域(let,const)
- 提供了定义类的语法糖(class)
- 新增了一种基本数据类型(Symbol)
- 新增了变量的解构赋值
- 函数参数允许设置默认值,引入了rest参数,新增了箭头函数
- 数组新增了一些API,如 isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法
- 对象和数组新增了扩展运算符
- ES6 新增了模块化(import/export)
- ES6 新增了 Set 和 Map 数据结构
- ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例
- ES6 新增了生成器(Generator)和遍历器(Iterator)
七、js设计模式有哪些
JS设计模式有很多,但我知道的有单例模式,观察者模式
-
单例模式:
就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
-
观察者模式:
观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。
总的来说,观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化
八、js面向对象
面向对象程序设计(Object-oriented Programming,简称为OOP)已经是当今主流的程序设计范型,但提到面向对象,就必须说一下面向过程,相信大多数学过计算机的人都接触并学习过c语言,c语言就是一门最具代表性的面向过程的语言。面向过程是一种以过程为中心的编程思想,主要是以什么正在发生为主要目标进行编程,而面向对象则关注的是谁在受影响,两者明显不同的就是封装、继承、类。
九、js数组常用的方法
- push :添加到数组末尾
- pop :删除数组末尾最后一个数据
- unshift :添加到数组开头
- shift :删除数组开头第一个数组
- splice :删除、替换数据
- join :将数组转换成字符串
- forEach :遍历数组
- map :映射
- sort :排序
- filter :过滤
- some :数组中只要有一个满足条件就返回true
- every :数组中每一项都满足条件时就返回true
十、js数组内置遍历方法有哪些区别?
forEach
这个方法是为了取代for循环遍历数组的。
let arrInfo=[4,6,6,8,5,7,87]
arrInfo.forEach((item,index,arr)=>{
//遍历逻辑
})
其中:
- item代表遍历的每一项
- index代表遍历的每项的索引
- arr代表数组本身
filter
这是一个过滤遍历的方法,如果返回条件为true,则返回满足条件的新数组
let arrInfo=[4,16,6,8,45,7,87]
let resultArr=arrInfo.filter((item,index,arr)=>{
//例如返回数组每项值大于9的数组
return item>9
})
map
这个map方法主要对数组的复杂逻辑处理时用的多,特别是react中遍历数据,也经常用到,写法和forEach类似
some
这个some方法用于只要数组中至少存在一个满足条件的结果,返回值就为true,否则返回fasel, 写法和forEach类似
every
这个every方法用于数组中每一项都得满足条件时,才返回true,否则返回false, 写法和forEach类似
十一、js作用域
JS作用域也就是JS识别变量的范围,作用域链也就是JS查找变量的顺序
- 先说作用域,JS作用域主要包括全局作用域、局部作用域和ES6的块级作用域
- 全局作用域:也就是定义在window下的变量范围,在任何地方都可以访问,
- 局部作用域:是只在函数内部定义的变量范围
- 块级作用域:简单来说用let和const在任意的代码块中定义的变量都认为是块级作用域中的变量,例如在for循环中用let定义的变量,在if语句中用let定义的变量等等
注: 1. 尽量不要使用全局变量,因为容易导致全局的污染,命名冲突,对bug查找不利。
2. 而所谓的作用域链就是由最内部的作用域往最外部,查找变量的过程.形成的链条就是作用域链
十二、从输入URL到页面加载中间发生了什么?
-
通过DNS服务器:url=>ip地址;
-
到达ip地址对应的服务器;
-
服务器接收用户的请求;
-
把处理后的结果返回给客户端;
-
客户端把结果渲染到浏览器即可,最后页面显示出来
输入了一个域名,域名要通过DNS解析找到这个域名对应的服务器地址(ip),通过TCP请求链接服务,通过WEB服务器(apache)返回数据,浏览器根据返回数据构建DOM树,通过css渲染引擎及js解析引擎将页面渲染出来,关闭tcp连接
十三、js事件代理(事件委托)是什么,实现原理是什么?
JS事件代理就是通过给父级元素(例如:ul)绑定事件,不给子级元素(例如:li)绑定事件,然后当点击子级元素时,通过事件冒泡机制在其绑定的父元素上触发事件处理函数,主要目的是为了提升性能,因为我不用给每个子级元素绑定事件,只给父级元素绑定一次就好了,在原生js里面是通过event对象的targe属性实现
var ul = document.querySelector("ul");
ul.onclick = function(e){//e指event,事件对象
var target = e.target || e.srcElement; //target获取触发事件的目标(li)
if(target.nodeName.toLowerCase() == 'li'){//目标(li)节点名转小写字母,不转的话是大写字母
alert(target.innerHTML)
}
}