【前端开发】Javascript中常见知识点、问题集合 (一)

436 阅读8分钟

闭包

  • 闭包就是能够读取其他函数内部变量的函数,即指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域。
  • 闭包特性:
    • 函数内再嵌套函数;
    • 内部函数可以引用外层的参数和变量;
    • 参数和变量不会被垃圾回收机制回收;
  • 闭包的优缺点:
    • 优点:能够实现封装和缓存等;
    • 缺点:消耗内存,使用不当会内存溢出;
    • 内存溢出解决方法:在退出函数之前,将不使用的局部变量全部删除。

变量对象

  • 变量对象,是执行上下文中的一部分,可以抽象为一种数据作用域,液可以理解为就是一个简单的对象,它存储着该执行上下文中的所有变量和函数生命,其中不包含表达式;
  • 活动对象(AO):当变量·对象所处的上下文为active EC 时,则称之为活动对象;

作用域

  • 作用域,可以简单理解为该上下文中声明的变量和声明的作用范围,可分为块级作用域和函数作用域,执行上下文中还包含作用域链。
  • 作用域链
    • 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的;
    • 简单来说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。

原型与原型链

  • 每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去prototype里找这个属性,这个 prototype又会有自己的prototype,于是就这样一直找下去,这也就是js中经常提及的原型链的概念;
  • 它们之间的关系:instance.constructor.prototype = instance._*proto*_
  • 特点: javascript对象是通过引用来传递的,我们创建的每个新对象实体中并未有一份属于自己的原型副本,当我们修改原型时,与之相关的对象也会继承这一改变,当我们需要一个属性的时候,javascript引擎会先看当前对象中是否有这个属性,如果没有就会查找它的Prototype对象是否有这个属性,如此地推下去,一直检索到Object内建对象。

事件委托

  • 事件代理(Event Delegation),又称之为事件委托,是javascript中常用的绑定事件的常用技巧,顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务,事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能;
  • 可以大量节省内存占用,减少事件注册,比如在table上代理所有的td的click事件就非常棒;
  • 可以实现当新增子对象时无需再次对其进行绑定。

实现继承的方法

  • 构造继承
  • 原型继承
  • 实例继承
  • 拷贝继承
  • 原型 prototype 机制或 apply call 方法去实现较简单,建议使用构造函数与原型混合方式
function Parent(){
  this.name = 'lili';
}

function Child(){
  this.age =  12;
}

Child.prototype = new Parent(); //继承了Parent,通过原型
var demo = new Child();
alert(demo.age);
alert(demo.name);//得到被继承的属性

This 对象的理解

  • this 总是指向函数的直接调用者(而非间接调用者)
  • 如果有 new 关键字, this 指向 new 出来的那个对象
  • 在事件中, this 指向触发这个事件的对象,特殊的是, IE 中的attachEvent 中的this 总是指向全局对象 Window

事件模型

W3C 中定义事件的发生经历三个阶段:捕获阶段( capturing )、目标阶段 ( targetin )、冒泡阶段( bubbling )

  • 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发
  • 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发
  • DOM 事件流:同时支持两种事件模型:捕获型事件和冒泡型事件
  • 阻止冒泡:在 W3c 中,使用 stopPropagation() 方法;在IE下设置 cancelBubble =true
  • 阻止捕获:阻止事件的默认行为,例如 click - a 后的跳转。在 W3c 中,使用preventDefault() 方法,在 IE 下设置 window.event.returnValue = false

new 操作符操作过程

  • 创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型
  • 属性和方法被加入到this引用的对象中;
  • 新创建的对象由this所引用,并且最后隐式的返回this

js基本数据类型

  • Undefined
  • Null
  • Boolean
  • Number
  • String
  • Bigint
  • Symbol

null与undefined的区别

  • undefined:表示不存在这个值;表示没有初始化的变量
  • null: 表示一个一个对象被定义了,值为"空”;是一个空对象,没有任何属性和方法;
  • 作为参数的时候,表示该函数的参数不是对象;

异步编程的实现方式

  • 回调函数
  • 事件监听
  • 发布/订阅(观察者模式)
  • Promise对象
  • Generator 函数
  • async函数

原生js

数据类型、运算、对象、Function、继承、闭包、作用域、原型链、事件、RegExp、JSON、Ajax、DOM、内存泄漏、跨域、异步装载、模板引擎、前端MVC、路由、模块化、ECMAScript等;

数组去重操作

  • ES6 Set
  • for 循环 indexOf
  • for 循环 inCludes
  • sort

js 原生拖拽节点

给需要拖拽的节点绑定mousedown、mousemove、mouseup 事件(需要注意浏览器边界值,设置拖拽范围)

  • mousedown时, 事件触发,开始拖拽;
  • mousemove 时,需要通过 event.clientX clientY获取拖拽位置,并实时更新位置;
  • mouseup 时,拖拽结束;

深拷贝、浅拷贝

  • 深拷贝: JSON.parse(JSON.stringity(object)) 深层递归
    • 所有的基础数据类型的赋值都是深拷贝
    • 通常利用基础数据类型的赋值来对引用数据类型做递归深拷贝
    • 局限性:会忽略 undefined,不能序列化函数,不能解决循环引用的对象
  • 浅拷贝: Object.assign 或者扩展运算符

节流防抖

  • 防抖:只有在某个时间内,没有再次触发某个函数,才真正的调用这个函数,一段时间内连续触发,不执行,直到超出限定时间执行最后一次。例如:input 模糊搜索;
    • 防抖的过程:
      • 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;
      • 当事件密集触发时,函数的触发会被频繁的推迟;
      • 只有等待了一段时间也没有事件触发,才会真正的执行响应函数;
    • 防抖应用场景:
      • 输入框中频繁的输入内容,搜索或者提交信息;
      • 频繁的点击按钮,触发某个事件;
      • 监听浏览器滚动事件,完成某些特定操作;
      • 用户缩放浏览器的resize事件;

简单的理解,当密集的事件触发,而我们只希望触发比较靠后发生的事件,就可以使用防抖函数;

  • 节流:在某个时间内(比如500ms),某个函数只能被触发一次,这就是节流,通常用在高频率触发的地方,降低频率。
    • 应用场景:
      • 监听页面的滚动事件;
      • 鼠标移动事件;
      • 用户频繁点击按钮操作;
      • 游戏中的一些设计;

实现防抖方法

方法一:利用第三方库,可以帮助我们实现防抖操作:

  • lodash
  • underscore

方法二:自定义防抖函数

与防抖类似,依然是密集的事件触发,但是这次密集事件触发的过程,不会等待最后一次才进行函数调用,而是会按照一定的频率进行调用;

ajax、axios、fetch区别

  • ajax
    • 基于原生的XHR 开发,XHR 本身的结构不清晰
    • 本身是针对MVC 的编程,不符合现在前端MVVM的浪潮
    • 依靠JQuery,JQuery 整个项目太大,单纯使用 ajax 却要引入整个 JQuery 非常的不合理(采取个性化打包的方案又不能享受CDN服务)
  • axios
    • 从浏览器中创建XMLHttpReqquest
    • 从node.js 发出http请求
    • 支持Promise API
    • 转换请求和响应数据
    • 取消请求
    • 自定转换JSON数据
    • 客户端支持防止CSRF/XSRF
  • fetch
    • 只对网络请求报错,对 400 , 500 都当做成功的请求,需要封装去处理
    • 对于 cookie 的处理比较特殊,不同浏览器对credentials的默认值不一样,也就使得默认情况下cookie变的不可控
    • 本身无自带 abort,无法超时控制,可以使用AbortController解决取消请求问题。没有办法原生监测请求的进度,而XHR可以

.....