javascript 基础知识记录

147 阅读16分钟

面试准备

基础

拿到一个面试题,第一时间看到->考点 如何看到做不完的题海-》不变应万变(题可变,考点不变) 如何对待接下来的题目-》题目到知识点,再到题目

类型判断

typeof

typeof 能判断哪些类型?(考点 js变量类型)

image.png

image.png

instanceof

image.png

何时使用===何时使用== (考点:强制类型转换)

  • 字符串拼接

image.png

  • == image.png

image.png

  • if语句

image.png

image.png

image.png

逻辑判断

image.png

值类型和引用类型的区别

image.png

window.onload 和DOMContentLoaded的区别? (考点:页面加载过程) 为什么样式放上面,js放下面

手写节流throttle。防抖debounce (考点:性能。体验优化)

promise 解决了什么问题? (考点:js异步,event loop) event loop

手写深拷贝

注意点:

  • 注意判断值类型和引用类型,值直接返回,引用递归处理
  • 注意判断是数组还是对象
const obj={
    age:20,
    name:'xxx',
    address:{
        city:'beijing'
    },
    arr:['a','b','c']
}
function deepclone(obj){
    if(typeof obj!=='object' || obj==null){
         return obj //obj是null,或者不是对象和数组,直接返回
    }
    let result
    if(obj instanceof Array){
        result =[]
    }else{
        result ={}
    }
    for(let key in obj){
    //保证key不是原型的属性
        if(obj.hasOwnProperty(key)){
             result[key]=deepclone(obj[key])
        }
    }
    return result
}

原型 && 原型链

class

子类使用extends 继承父类

子类使用super传入参数

classs Perple(){
    constructor(name){
        this.name=name
    }
    eat(){} //可以继承
    static see(){} //不可继承私有
}
class Student extends Perple {
    constructor(name,number){
        super(name) //继承父类
        this.number=number
    }
    sayHi(){ //子类自己的方法
        console.log('姓名'+this.name+this.number)
    }
}

const xialuo=new Student('ludan',100)
console.log(xialuo.name)
console.log(xialuo.number)
ludan.eat()
ludan.see()

image.png

image.png

总结:

  • 每个class都有显示原型prototype
  • 每个实例都有隐藏原型__proto__
  • 实例的__proto__指向对应class的protorype

基于原型的执行规则

  • 获取属性xialuo.name或执行方法xialuo.eat()时
  • 先在自身属性和方法寻找
  • 如果找不到则自动去隐式原型查找

原型链

image.png

如何准确判断一个变量是不是数组?

a instanceof Array
Object.prototype.toString.call(arg)==='[object Array]'

作用域和闭包

  • this的不同应用场景,如何取值?
当做变通函数被调用
使用call apply bind
作为对象方法调用
在class的方法中调用昌当前实例本身
箭头函数找的是上级的作用域
  • 实际开发中闭包的应用场景,举例说明
隐藏数据,只提供API
function createCache(){
    const data={}
    return {
        set:function(key,val){
          data[key]=val  
        },
        get:function(){
            return data[key]
        }
    }
}
const c=createCache()
c.set('a',100)
console.log(c.get('a'))

闭包

闭包应用的特殊情况,有两种表现:

  • 函数作为参数被传递
  • 函数作为返回值被返回

自由变量

!!!所有的自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方

image.png

作用域

let a=0
function fn1(){
    let a1=100
    function fn2(){
        let a2=200
        function fn3(){
            let a3=300
            return a+a1+a2+a3
        }
        fn3()
    }
    fn2()
}
fn1()

this

this是在确认是在执行的时候确认的

function fn1(){
   console.log(this)
   fn1()
   fn1.call({x:100})
   const fn2=fn1.bind({x:200})
   fn2()
}

image.png

js创建10个a标签,点击的时候弹出对应的序号 (考点:作用域)

let i,a
    for(i=0;i<10;i++){
      a=document.createElement('a')
      a.innerHTML=i+'<br>'
      a.addEventListener('click',function(e){
        e.preventDefault()
        alert(i)
      })
      document.body.appendChild(a)
    }
    
    修改把letfor的块级作用域里
    let a
    for(let i=0;i<10;i++){
      a=document.createElement('a')
      a.innerHTML=i+'<br>'
      a.addEventListener('click',function(e){
        e.preventDefault()
        alert(i)
      })
      document.body.appendChild(a)
    }

异步和单线程

题目

image.png

  • js是单线程的最早操作DOM 同步
  • 但是加入请求需要异步,
  • 异步不会阻塞代码执行 (网络请求,如ajax图片加载,定时任务,如setTimeout)
  • 同步会阻塞代码执行

image.png

promise 加载一张图片

function loadImg(src){
    return new promise((resolve,reject)=>{
        const img=document.createElement('img')
        img.onload=()=>{
            resolve(img)
        }
        img.onerror=()=>{
            const err=new Error('图片加载失败 ${src}')
            reject(err)
        }
        img.src=src
    })
}

image.png

  • 请描述Event loop(事件循环/事件轮询)的机制
  • 什么是宏任务和微任务,两者有什么区别?
  • promise有哪三种状态?如何变化 ?

场景题

image.png

image.png

image.png

image.png

js如何执行

  • 从前到后,一行一行执行
  • 如果某一行执行报错,则停止下面代码的执行
  • 先把同步代码执行完,再执行异步代码

event loop过程1

  • 同步代码,一行一行放在Call Stack执行
  • 遇到异步,会先记录下,等待时机(定时,网络请求等)
  • 时机到了,就移动到Callback Queue
  • 如Call Stack为空(即同步代码执行完)Event loop开始工作
  • 轮询查找Callback Queue,如有则移动到Call Stack执行
  • 然后继续轮询查找(永动机一样)

image.png

image.png

promise

  • 三种状态
pending resolved rejected
pending->resolved 或 peding->rejected
变化不可逆
  • 状态的表现和变化
pending状态,不会触发then和catch
resolved状态,会触发后续的 then回调函数
rejected状态,会触发后续的catch回调函数
  • then和catch对状态的影响
then 正常返回resolved,里面有报错则返回rejected
catch正常返回resolved,里面有报错则返回rejected

image.png

image.png

async/await

  • 异步回调callback hell
  • promise then catch链式调用,但也是基于回调函数
  • async/await是同步语法,彻底消灭回调函数

image.png

image.png

async/await和Promise的关系

  • 执行async函数,返回的是promise对象
async function fn1(){
    //return 100 相当于 return Promise.resolve(100)
    return Promise.resolve(200)
}
const res1=fn1() //执行async函数,返回的是一个 Promise对象
//console.log('res1',res1) //Promise对象
res1.then(data=>>{
    console.log(data) //200
})对象

  • await相当于promise的then

image.png 特殊情况的处理,以下这个就执行不了可以使用try catch捕获 image.png

后面跟函数形式 image.png

image.png

  • try...catch可捕获异常,代替了promise的catch

image.png

for...of

  • for...in(以及forEach for)是常规的同步遍历
  • for...of 常用于异步的遍历

image.png 代码结果会同步出现 1 4 9

如果以下代码想实现先出1,过1秒出4,再过一秒出9

![image.png](p1-juejin.byteimg.com/tos-cn-i- k3u1fbpfcp/e93f47bb094747f78c4c4d1e290329e8~tplv-k3u1fbpfcp-watermark.image?)

image.png

宏任务和微任务

image.png

image.png image.png

  • 微任务是ES6语法规定
  • 宏任务是由浏览器规定的

image.png

image.png

宏任务微任务都有哪些

image.png

js Web Api--DOM

知识点:

DOM BOM ajax 事件绑定 存储

题目-DOM

  • DOM是哪种数据结构
  • DOM操作的常用API
  • attr和property的区别
  • 一次性插入多个DOM节点,考虑性能

DOM本质

DOM本质是一层层往下的树

获取DOM

image.png

DOM节点的property

image.png

DOM节点的attribute

const pList=document.querySelectorAll('p')
const p=pList[0]
p.getAttribute('data-name')
p.getAttribute('data-name','ludan')

property attribute区别

  • property:修改对象属性,不会体现到html结构中
  • attribute:修改html属性,会改变html结构
  • 两者都有可能引起DOM重新渲染

DOM 结构操作

  • 新增/插入节点

image.png

  • 获取子元素列表,获取父元素

image.png

image.png

  • 删除子节点

image.png

DOM性能

  • DOM操作非常昂贵,避免频繁的DOM操作
  • 对DOM查询做缓存

image.png

  • 将频繁操作改一次性操作

image.png

BOM

navigator history screen location

题目

  • 如何识别浏览器的类型
  • 分析拆解url各个部分

navigator 和 screen

image.png

location 和 history

image.png

事件

题目

  • 编写一个通用的事件监听函数

image.png

  • 描述事件冒泡的流程

image.png

  • 事件代理

image.png

image.png

image.png

  • 件流分为三个阶段:

    • 捕获事件阶段
    • 处于目标阶段
    • 冒泡事件阶段
  • 无限下拉的图片列表,如何监听每个图片的点击?

image.png

封装事件函数

function bindEvent(elm,type,selector,fn){
    if(fn==null){
        fn=selector
        selector=null
    }
    elem.addEventListener(type,(event)=>{
        const target=event.target
        if(selector){
            //代理绑定
            if(target.matches(selector)){ //判断是否符合选择器
                fn.call(target,event)
            }
        }else{
            //普通绑定
            fn.call(target,event)
        }
    })
}

ajax

知识点

题目

  • 手写一个简易的ajax

    • 知识点:XMLHttpRequest
    • 状态码
    • 跨域:同源策略,跨域解决方案

image.png POST

image.png

xhr.readyState

image.png

xhr.status

2XX-表示成功处理请求,如200
3XX-需要重定向,浏览器直接跳转,如301 302 304
4XX-客户端请求错误,如404  403
5XX-服务器端错误
  • 跨域的常用实现方式

跨域 (同源策略)

- ajax请求时,浏览器要求当前网页和server必须同源(安全)
- 同源:协议。域名,端口 三者必须一致
- 前端 http://a.com:9090;server:https://b.com/api/xxx
- 加载图片css js可无视同源策略
<img src='' />  可用于统计打点,可使用第三方统计服务
<link href='' />
<script> 
link script可使用CDNCDN一般都是外域
script可实现JSONP
- 所有的跨域,都必须经过server端允许和配合
- 未经server端允许就实现跨域,说明浏览器有漏洞,危险信号
  • JSONP

image.png

window.callback=function(data){
      //这是我们跨域得到信息
      console.log(data)
    }
    <script src='https://baidu.com/getData.js'></script>
    <!--将返回 callback({x:100,y:200})-->

image.png

  • CORS(服务端支持)

image.png

fetch请求

developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

存储

题目

  • 描述cookie localStorage sessionStorage区别

cookie

image.png 缺点

image.png

localStorage sessionStorage

image.png

image.png

http

题目

  • http常见的状态码有哪些?

    • 1xx 服务器收到请求
    • 2xx 请求成功 200
    • 3xx 重定向 如302
      • 301 永久重定向(配合location浏览器自动处理)
      • 302 临时重定向(配合location浏览器自动处理 tnnnnn【
      • 同)
      • 304 资源未被修改
    • 4xx 客户端错误 如404
      • 404 资源未找到
      • 403 没有权限
    • 5xx 服务端错误 如500
      • 500 服务器错误
      • 504 网关超时
  • http methods

    • 传统的methods
    • 现在的methods
      • get获取数据
      • post新建数据
      • patch/put 更新数据
      • delte删除数据
  • 什么是Restful API

    • 一种新的API设计方法
    • 传统API设计:把每个url当做一个功能
    • Restful API设计:把每个url当做一个唯一的资源
      • 尽量不用url参数
      • 用method表示操作类型
  • method 表示操作类型(传统API设计)

    • post请求 /api/create-blog
    • post请求 /api/update-blog?id=100
    • get请求 /api/get-blog?id=100
  • http常见的header有哪些?

    • 常见的Request Headers
      • Accept 浏览器可接收的数据格式
      • Accept-Encoding浏览器可接收的压缩算法,如gzip
      • Accept-Languange浏览器可接收的语言,如zh-CN
      • Connection:keep-alive 一次TCP连接重复使用
      • cookie
      • Host
      • User-Agent (简称UA)浏览器信息
      • Content-type 发送数据的格式,如application/json
    • 常见的Response Headers
      • Content-type 返回数据的格式,如application/json
      • Content-length 返回数据的大小,多少字节
      • Content-Encoding 返回数据的压缩算法,如gzip
      • set-cookie
  • 自定义header

image.png

  • 缓存相关的headers
    • Cache-Control Expires
    • Last-Modified If-Modified-Since
    • Etag If-None-Match

http 缓存

  • 描述一下 http的缓存机制(重要)

关于缓存

  * 什么是缓存 (不变化的数据可以缓存起来,不用每次都重新加载)
  * 为什么需要缓存(让网页加载更快)
  * 哪些资源可以被缓存?一静态资源(js css img)

http缓存-强制缓存

Cache-Control

Cache-Control的值 :
max-age (可以设置缓存过期的最大时间)
no-cache(不用本地强制缓存,交给服务端处理)
no-store(我们不用本地缓存,不用服务端的缓存)
private (只允许最终用户做缓存)
public  (只允许中间代码,路由做缓存)

image.png

Expires

同在Response Headers中
同为控制缓存过期
已被Cache-Control代替

hrrp缓存-协商缓存

  • 服务器端缓存策略 (服务端会告诉前端这个数据没有变,使用前端缓存)
  • 服务器判断客户端资源,是否和服务端资源一样
  • 一致则返回304,否则返回200和最新的资源

image.png

Response Headers中,有两种
Last-Modified资源的最后修改时间
Etag资源的唯一标识(一个字符串,类似人类的指纹)

会优先使用 Etag
last-Modified只能精确到秒级
如果资源被重复生成,而内容不变,则Etag 更精确

image.png

image.png

请求的事例 image.png

image.png

总结缓存

image.png

三种刷新操作,不同刷新,不同的缓存策略

  • 正常操作:地址栏输入url,跳转链接,前进后退等
  • 手动刷新:F5,点击刷新按钮,右击菜单刷新
  • 强制刷新:Ctrl+F5

强制刷新对缓存影响

正常操作:强制缓存有效,协商缓存有效
手动刷新:强制缓存失效,协商缓存有效
强制刷新:强制缓存失效,协商缓存失效

image.png

关于开发环境

git 代码版本管理工具(大型项目需要多人协作开发,必须熟用git)
调试工具
抓包
webpack babel
linux 常用命令

git常用命令

git add .
git checkout xxx
git commit -m 'xxx'
git push origin master
git pull origin master
git branch
git checkout -b xxx
git merge xxx
git show 版本号  查看某次的修改

在commit之前
git checkout . 撤销所有修改
git checkout index.html //撤销本次修改

git checkout -b xxx 创建新分支

git fetch //拉取所有分支

忘记在master分支上改了怎么办
git stash  先把修改分支分在一边其他区域
git status
git checkout -b xxx  这时就可以切换分支了
切到新分支后把之前暂时存起来的修改放出来
git stash pop
接下来就是把修改的在当前分支做添加操作了

chrome 调试工具

Elements 
Console
debugger
Network
Application

抓包

  • 移动端h5页,查看网络请求,需要用工具抓包
  • windows一般用fiddler
  • Mac OS一般用charles

抓包过程

手机和电脑连同一个局域网
将手机代理到电脑上
手机浏览网页,即可抓包

抓包设置 charles为例

  • 查看网络请求
  • 网址代理
  • https
    • proxy/SSL Proxying Settings 开启 Enable SSl Proxing

image.png

image.png 手机下载安装证书 image.png

webpack 和 babel

  • ES6 模块化,浏览器暂时不支持
  • ES6语法,浏览器并不完全支持
  • 压缩代码,整合代码,以让网页加载更快

babel

babel是把js高版本语法转成es5

ES6 模块化导出导入注意事项

第一想清楚是使用结构的方式,导出就不能用default
import {fn,a} from ‘./b’

b.js
export fn(){}
export const a=5
或者
function fn(){}
const a=5
export {
    fn,
    a
}

第二种情况下,不使用结构,default导出

import xxx from './b'

b.js
function fn(){}
const a=5
export default {
    fn,
    a
}

运行环境

  • 运行环境即浏览器(server端有nodejs)
  • 下载网页代码,渲染出页面,期间会执行若干js
  • 要保证代码在浏览器中:稳定且高效
知识点
加载资源的形式
    * html代码
    * 媒体文件,如图片,视频等
    * javascript css
加载资源的过程
    * DNS解析:域名-》IP地址
    * 浏览器根据IP地址向服务器发起http请求
    * 服务器处理http请求,并返回浏览器
渲染页面的过程
    * 根据HTML代码生成DOM Tree
    * 根据CSS代码生成CSSOM
    * 将DOM TreeCSSOM整合形成Render Tree
    * 根据Render Tree渲染页面
    * 遇到<script>则暂停渲染,优先加载并执行js代码,完成再继续
    * 直至把Render Tree渲染完成

题目

  • 从输入url到渲染出页面的整个过程
  • window.onload和 DOMContentLoaded的区别

image.png

网页加载过程

为什么把js放到最后

js文件如果放在上面或者中间,也会出现一边改一边渲染,js会阻止渲染让渲染整个页面时间加长

为什么把css放到header中

因为放到heder里直接把css直接生成CSSOM,然后和DOM Tree直接合并生成render Tree 如果放到body里,假如生成一个结构了,后面又修改css二次渲染

性能优化

性能优化原则

多使用内存,缓存或其他方法
减少CPU计算量,减少网络加载耗时
(适用于所有编程的性能优化--空间换时间)

让加载更快

  • 减少资源体积:压缩代码
  • 减少访问次数:合并代码,SSR服务器端渲染,缓存
  • 使用更快的网络:CDN

让渲染更快

  • CSS放在head,js放在body最下面
  • 尽早开始执行js,用DOMContentLoaded触发
  • 懒加载(图片懒加载,上滑加载更多)
  • 对DOM查询进行缓存
  • 频繁DOM操作,合并到一起插入DOM结构
  • 节流throttle 防抖debounce

缓存

  • 静态资源加hash后缀,根据文件内容计算hash
  • 文件内容不变,则hash不变,则url不变
  • url和文件不变,则会自动触发http缓存机制,返回304

CDN

image.png

SSR

image.png

懒加载

image.png ()

缓存DOM查询

image.png

多个DOM操作一起插入到DOM结构

image.png

防抖 debounce

  • 监听一个输入框的,文字变化后触发change事件
  • 直接用keyup事件,则会频发触发change事件
  • 防抖:用户输入结束或暂停时,才会触发change事件
原理利用定时器,每次开始就把上次的定时器操作清空,重新开始
function debounce(fn,delay=500){
    const timer=null
    
    return function(){
        if(timer){
            clearTimeout(timer)
        }
        timer=setTimeout(()=>{
            fn.apply(this,arguments) //需要用this外面传入函数就不能用箭头函数
        },delay)
    }
}

节流 throttle

  • 拖拽一个元素时,要随时拿的到该元素被拖拽的位置
  • 直接用drag事件,则会频发触发,很容易导致卡顿
  • 节流:无论拖拽速度多快,都会每隔100ms触发一次
function throttle(fn,delay=500){
    let timer=null
    return function(){
        if(timer){
            return
        }
         timer=setTimeout(()=>{
            fn.apply(this,arguments) //需要用this外面传入函数就不能用箭头函数
            timer=null
        },delay)
    }
}

安全

  • 常见的web前端攻击方式有哪些?
xss 跨站请求攻击
    * 发表嵌入script脚本
    * 获取cookie,发送到我的服务器(服务器配合跨域)
    * 有人查看就可以轻松收割访问者的cookie
    
    预防
    把script括号用特殊字符替换
    使用工具 npmjs.com/package/xss
xsrf 跨站请求伪造

面试真题

题1

  • var和let const的区别
    • var是ES5语法,let const 是ES6语法,var有变量提升
    • var和let是变量,可修改,const是常量,不可修改
    • let const有块级作用域,var没有
  • typeof返回哪些类型

image.png

  • 列举强制类型转换和隐匿类型转换

image.png

题2

  • 手写深度比较,模拟lodash isEqual
function isObject(obj){
      return typeof obj==='object' && obj!==null
    }
    function isEqual(obj1,obj2){
      if(!isObject(obj1) || !isObject(obj2)){
        return obj1===obj2
      }
      if(obj1===obj2){
        return true
      }
      //两个都是对象或者数组,而且不全等
      //1先取出obj1 obj2的个数
      const obj1Keys=Object.keys(obj1)
      const obj2Keys=Object.keys(obj2)
      if(obj1Keys.length!=obj2Keys.length){
        return false
      }
      for(let key in obj1){
        const res=isEqual(obj1[key],obj2[key])
        if(!res){
          return false
        }
      }
      return true
    }

    const obj1={
      a:100,
      b:{
        x:100,
        y:200
      }
    }
    const obj2={
      a:100,
      b:{
        x:100,
        y:200
      }
    }
    console.log('isEqual=='+isEqual(obj1,obj2))
  • split()和join()的区别

image.png

  • 数组的pop push unshift shift 分别做什么
    • 功能是什么?
    • 返回值是什么
    • 是否对原数组有影响

image.png 纯函数:1不改变源数组(没有副作用)

image.png

题目3

  • 数组slice和splice的区别
    • 功能区别(slice-切片,splice-剪接)
    • 参数和返回值
    • 是否纯函数?

image.png

  • [10,20,30].map(parseint)返回结果是什么

image.png

image.png

  • ajax请求get和post的区别
    • get 一般用于查询操作,post一般用户提交操作
    • get参数拼接在url上,post在请求体内(数据体积可更大)
    • 安全性:post易于防止CSRF

题目4

  • 函数call和apply的区别

image.png

  • 事件代理委托是什么

image.png

  • 闭包是什么,有什么特性,有什么负面影响
    • 作为参数被传入,作为返回值被返回
    • 自由变量的查找,要在函数定义的地方(而非执行的地方)
    • 变量会常驻内存,得不到释放,闭包不要乱用

image.png

题目5

image.png

image.png

image.png

img script

题目7

  • 函数声明和函数表达式的区别

image.png

  • new Object()和Object.create()区别

image.png

  • 关于this,使用场景

image.png this值在执行的时候才能确定是谁

题目8

  • 关于作用域和自由变量的场景题-1

image.png

  • 判断字符串以字母开头,后面字母数字下划线,长度6-30

image.png

deerchao.cn/tutorials/regex/regex.html

  • 关于作用域和自由变量的场景题-2