Javascript基础

170 阅读9分钟

Javascript基础

1. 原始数据类型、内置对象

原始类型存储的是值,对象类型存储的是地址(指针)

(1)原始类型包含:boolean、null、undefined、number、string、symbol

(2)对象类型:Object、数组、函数

(3)理解typeof 和 instanceof

  • typeof:是判断参数是什么类型的实例,返回值为说明运算数类型的字符串。
    • 返回值结果:“number”、“string”、“boolean”、“object”、“function”、“undefined”
    • 若参数为引用类型,始终返回“object”,对于Array、null始终返回“object”,所以用typeof来判断参数类型有很大的局限性。
  • instanceof:用来判断一个对象在其原型链中是否存在一个构造函数的prototype属性
    • a instanceof b:判断a是否为b的实例,可以用于继承关系中
    • b是c的父对象,a是c的实例,a instanceof b 与 a instanceof c 结果均为true

2. 类型转换

在 JS 中类型转换只有三种情况,分别是

  • 转换为布尔值:Boolean() 除了以下6个转化为false,剩下都是true

    • undefined
    • null
    • -0
    • +0
    • NaN
    • ‘’(空字符串)
  • 转换为数字:Number()

  • 转换为字符串

    • String() :该方法可用于任何类型的数字,字母,变量,表达式
    • toString()
  • 加法运算符不同于其他几个运算符,它有以下几个特点:

    • 运算中其中一方为字符串,那么就会把另一方也转换为字符串
    • 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串

3. this

  • 默认绑定
    • 适用于没有明确的调用对象,this指向全局对象,即window对象
    • 严格模式下为 (undefined)
  • 隐式绑定
    • 通过对象调用方法,this指向此对象
  • 显式绑定
    • 使用apply和call函数
    • 使用bind 函数
  • new 绑定
  • 箭头函数

4. 错误处理

  • Error 对象
  • 常见 Error 类型
    • EvalError:eval函数没有被正确执行时,会抛出EvalError错误

    • InternalError:示出现在JavaScript引擎内部的错误,是当它有太多数据要处理并且堆栈增长超过其关键限制时

      • “too many switch cases”(过多case子句)
      • “too many parentheses in regular expression”(正则表达式中括号过多);
      • “array initializer too large”(数组初始化器过大);
      • “too much recursion”(递归过深)。
    • SyntaxError:语法错误

      • 例子:var 123
    • TypeError:类型错误,在作用域中找到了但是做了不是自己该做的事情

      • 例子:var fn1; fn1();
    • URIError: URI相关函数的参数不正确时抛出的错,主要涉及encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。

      • 例子:decodeURI('%2')
    • ReferenceError: 引用错误 ,在作用域中找不到,引用了不存在的变量而发生了错误。

    • 范围错误:范围错误,超出有效范围时发生的错误

      • 例子:[].length = -20;
  • 异常和错误区别:错误对象只有在抛出时才会变成异常
    • 使用 try / catch / finally
    • 使用 Promise 处理异常: .then / .catch / .finally

5. 理解 == 和 ===

  • === 严格相等,会比较两个值的类型和值
  • ==  抽象相等,比较时,会先进行类型转换,然后再比较值

6. 闭包

  • 闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。

7. 正则表达式

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式,一般用于文本搜索和文本替换。

(1)正则表达式相关方法: test、exec、match

  • test:方法用于正则表达式模式在字符串中运行查找,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null
  • exec:用于检索字符串中的正则表达式的匹配。 返回值是一个数组,但是此数组的内容和正则对象是否是全局匹配有着很大关系
    • 没有g修饰符: 此函数的作用和match()函数是一样的,只能够在字符串中匹配一次,如果没有找到匹配的字符串,那么返回null,否则将返回一个数组,数组的第0个元素存储的是匹配字符串
    • 具有g修饰符 : 此函数返回值同样是一个数组,并且也只能够在字符串中匹配一次。不过此时,此函数一般会和lastIndex属性匹配使用,此函数会在lastIndex属性指定的字符处开始检索字符串,当exec()找到与表达式相匹配的字符串时,在匹配后,它将lastIndex 属性设置为匹配字符串的最后一个字符的下一个位置。可以通过反复调用exec()函数遍历字符串中的所有匹配,当exec()函数再也找不到匹配的文本时,它将返回null,并把lastIndex 属性重置为0。
  • match : 检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。

(2)常用的标志(flags)或修饰符(modifiers)

  • g: 全局搜索,当成功匹配后不会直接返回。
  • i: 不区分大小写搜索。

(3)常见正则表达式书写

8. 深浅拷贝(所谓拷贝,就是赋值)

(1)浅拷贝

  • 定义:加了一个指针指向已存在的内存地址

  • 方法 :

    • 1. 手写浅拷贝
    function shallowCopy(obj) {
       if (typeof obj === 'object' && obj != null) {
    
          let copy = Array.isArray(obj) ? [] : {};
          for (var p in obj) {
             copy[p] = obj[p];
          }
          return copy;
     } else {
        return obj;
     }
    }
    
    • 2.对象 Object.assign() Object.assign(target, ...sources) 来实现浅拷贝,第一个参数 target是目标对象,后面的参数...sources是原对象 注: Object.assign() 一般用于对象的浅拷贝,用来处理数组时,会把数组视为对象。
    // Object.assign 把数组视为属性名为 0、1、2 的对象
    // 源数组的 0 号属性 7 覆盖了目标数组的 0 号属性1,以此类推
    Object.assign([1,2,3], [7,8]); // [7,8,3]
    Object.assign([1,2], [6,7,8]); // [6,7,8]
    
    
    • 3. 数组 Array.concat()
    • 4. 扩展运算符{...obj}

(2)深拷贝

  • 定义:是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存

  • 方法

    • 1. 浅拷贝+递归
    //递归浅拷贝
    function recursiveShallowCopy (obj){
       var copy = Array.isArray(obj) ? [] : {};
       for(let p in obj){
          if(typeof obj[p] ==='object'){
             copy[p] = recursiveShallowCopy(obj[p])
          }else{
             copy[p] = obj[p];
          }
       }
       return copy;
    
    }
    
    //深拷贝
    function deepCopy(obj) {
       if (typeof obj === 'object' && obj != null) {
          return recursiveShallowCopy(obj);
       } else {
          return obj;
       }
    }
    
    • 2. JSON.parse(JSON.stringify())

    先通过**JSON.stringify()把原对象序列化成一个 JSON 字符串,再通过JSON.parse()**生成一个新对象。

    缺陷:

    1.如果原对象中有undefined、Symbol、函数时,会导致该键值被丢失
    2.如果原对象中有正则,会被转换为空对象{}
    3.如果原对象中有Date,会被转换成字符串
    4.会抛弃原对象的constructor,都会被转换成Object
    5.如果对象中存在循环引用的情况,无法正确处理

注:使用JSON.parse(JSON.stringify()实现深拷贝的前 4 个缺陷,可以通过递归+浅拷贝的深拷贝方式解决,但递归+浅拷贝不能解决第 5 点循环引用的问题

9. 原型、原型链

juejin.cn/post/684490…

prototype.png

10. var、let、const 区别

  • ES5只有 var,ES6 引入了let 和 const,在开发中应该避免使用 var
  • var 允许变量提升,可以在申明前使用,let 和 const 不允许
  • var 允许重复申明,let 和const不允许
  • var、let不需要初始值,const需要初始值
  • let和const支持块级作用域,var不支持

11. 继承

12. map, filter, reduce 用法

  • map 作用是生成一个新数组,遍历原数组,将每个元素拿出来做一些变换然后放入到新的数组中
  • filter 的作用也是生成一个新数组,在遍历数组的时候将返回值为 true 的元素放入新数组
  • reduce 可以将数组中的元素通过回调函数最终转换为一个值

14. 异步编程

(1) 回调函数 Callback

例如

function step1(cb) {
    console.log("step1");
    cb()
}

function step2(){
    console.log("step2");
}

step1(step2);  // step1  step2

(2) Generator

(3) Promise

理解三种状态 Pending、Resolved、Rejected 理解和使用 then / catch / finally 使用async / await

15. 定时器函数

setTimeout setInterval requestAnimationFrame

16. EventLoop

宏任务 / 微任务概念 而宏任务一般是:包括整体代码script,setTimeout,setInterval、setImmediate。 微任务:原生Promise(有些实现的promise将then方法放到了宏任务中) 4. 前端安全 XSS XSS 简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中 防御方法 用于不要新人用户的输入。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义 CSP,本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行

CSRF CSRF 中文名为跨站请求伪造。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。防范 CSRF 攻击可以遵循以下几种规则: Get 请求不对数据进行修改 不让第三方网站访问到用户 Cookie 阻止第三方网站请求接口 请求时附带验证信息,比如验证码或者 Token 中间人攻击 中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。如何防御: 不建议使用公共的 Wi-Fi 使用HTTPS 来防御中间人攻击

  1. 兼容性 移动端兼容性问题 移动端点击延时300ms的问题 移动端 300ms 延时的由来(支持双击缩放,需要延时300ms来检测是点击还是双击) 使用fastclick库,原理: 在touchend之后生成一个click事件,并立即触发这个click,再取消原本的click事件 通过禁用缩放(缺点:无法使用缩放效果) 设置viewport默认宽度为device-width(浏览器认为该网站做过移动端适配,所以无需双击缩放) 移动设备浏览器上常用的内核: iPhone 和 iPad 等苹果 iOS 平台主要是 WebKit Android 4.4 之前的 Android 系统浏览器内核是 WebKit Android 4.4 系统浏览器切换到了Chromium,内核是 Webkit 的分支 Blink IE 兼容性问题 polifill 是指通过一段代码来实现浏览器暂未提供的一些特性,以下常用API在IE都不支持,需要做 Polyfill: Promise Fetch API Object.assign Array.from ... React 15起,官方停止React Dom对IE8 的支持 最新版本的React可以通过官方的polyfill支持IE9、IE10、IE11