常见面试题之JavaScript(1)

JS由哪三部分组成?

  • ECMAScript:JS的核心内容,描述了语言的基础语法,比如var,for,数据类型(数组、字符串)

  • 文档对象模型(DOM):DOM把整个HTML页面规划为元素构成的文档

  • 浏览器对象模型 (BOM):对浏览器窗口进行访问和操作

一元运算符、二元运算符和三元运算符

  • 一元运算符:正号+、负号-、++、--

  • 二元运算符:算术运算符(加减乘除)、关系运算符(==、!=、>、<)

  • 三元运算符:唯一的具有三个操作数的运算符。条件 ? 表达式1 : 表达式2 如果条件为真,则返回表达式1的值,否则返回表达式2的值。

条件语句

  1. switch-case-default

    • 要判断某一个变量 等于 某一个值的时候使用

    • 必须写break

    • 性能好,可以精准匹配

    switch (要判断的变量) {
        case 情况1:
          情况1要执行的代码
          break;
        case 情况2:
          情况2要执行的代码
          break;
    ​
        default:
          上述情况都不满足的时候执行的代码
    }
    ​
    let code = 1
      switch (code) {
        case 0:
          document.write('未付款');
          break;
        case 1:
          document.write('已付款');
          break;
        case 2:
          document.write('已发货');
          break;
        case 3:
          document.write('已完成');
          break;
    ​
        default:
         document.write('未知状态');
    }
  2. while

    • 当条件满足时执行,一旦不满足就不执行

    • 语法:while(条件){满足添加就执行}

    • 满足条件就执行,所以我们写的时候要设定一个边界值,不然会出现死循环

  3. do-while

    • 和while类似,但是do-while循环是先不管条件,直接执行一次,然后再开始进行条件判断

    • 语法:do{要执行的代码} while (条件)

  4. for循环

    • 也是循环的结构

    • 语法:for(var i=0;i<10;i++){要执行的代码}

      (把初始化,条件判断,自身改变) 写在一起了

      • 先赋初始值,然后判断,符合条件执行代码,执行完改变自身,然后再赋值再判断,以此类推

JS有哪些内置对象?

  • 数据封装类对象:ObjectArrayBooleanNumberString

  • 其他对象:FunctionArgumentsMathDateRegExpError

  • ES6新增对象:SymbolMapSetPromiseProxyReflect

  • 常用的有:

    • Math

      • Math.max():返回一组数字中的最大值。

      • Math.min():返回一组数字中的最小值。

      • Math.abs():返回一个数的绝对值。

      • Math.sqrt():返回一个数的平方根。

    • Date

      • new Date():创建一个表示当前日期和时间的 Date 对象。

      • getFullYear():获取 Date 对象的年份。

      • getMonth():获取月份(0-11,0 表示一月)。

      • getDate():获取日期(1-31)。

      • getDay():获取星期几(0-6,0 表示星期日)。

      • getHours():获取小时(0-23)。

      • getMinutes():获取分钟(0-59)。

      • getSeconds():获取秒(0-59)。

      • getTime():返回自 1970 年 1 月 1 日 00:00:00 UTC 起至当前时间的毫秒数。

      • setFullYear():设置年份。

      • setMonth():设置月份。

      • setDate():设置日期。

      • setHours():设置小时。

      • setMinutes():设置分钟。

      • setSeconds():设置秒。

    • Array

      • concat():连接两个或多个数组,并返回一个新数组。

      • join():将数组中的所有元素连接成一个字符串。

      • pop():删除并返回数组的最后一个元素。

      • push():向数组的末尾添加一个或多个元素,并返回新的长度。

      • shift():删除并返回数组的第一个元素。

      • unshift():向数组的开头添加一个或多个元素,并返回新的长度。

      • reverse():颠倒数组中元素的顺序。

      • sort():对数组进行排序。

      • slice():选取数组的一部分,并返回一个新数组。

      • splice():删除、替换或插入元素到数组中,并返回被删除的元素组成的新数组。

      • indexOf():返回指定元素在数组中首次出现的索引。

      • lastIndexOf():返回指定元素在数组中最后一次出现的索引。

      • forEach():对数组中的每个元素执行一个函数。

        // 1.没有返回值
        // 2.不能使用break
        // 3.遍历的是item
        let arr = ['a','b','c']
        let res = arr.forEach(item=>{
            console.log(item)
            break;
            return item + '0'
        })
        console.log(res)

      • map():对数组中的每个元素执行一个指定的函数,并返回一个新数组。

        // 1.有返回值(数组)默认return是undefined
        // 2.接受的参数是一个函数(key,value)
        // 3.不能用break打断
        let arr = ['a','b','c']
        let res = arr.map((value,key)=>{
            return value + '0'
        })
        console.log(res)
      • filter():根据指定条件过滤数组中的元素,并返回一个新数组。

        let a = [1,2,3,14,15]
        // current当前值;index当前值的下标;array这个数组对象
        let b = a.filter((current,index,array)=>{
            return current > 10
        })
        console.log(a)
        console.log(b)
      • reduce():从左到右对数组中的每个元素执行一个归并操作,返回一个累计的值。

      • reduceRight():从右到左对数组中的每个元素执行一个归并操作,返回一个累计的值。

      • some():检查数组中是否至少有一个元素满足指定条件。

      • every():检查数组中的所有元素是否都满足指定条件。

      • find():返回数组中满足指定条件的第一个元素。

      • findIndex():返回数组中满足指定条件的第一个元素的索引。

      • includes():判断数组是否包含指定元素。

      • toString():将数组转换为字符串,并返回结果。

      • isArray():用于检测一个值是否为数组。

      Vue中的7个变异方法:

      pop()push()shift()unshift()reverse()sort()splice()

    • String

      • length:返回字符串的长度。

      • charAt():返回指定索引位置的字符。

      • concat():连接两个或多个字符串,并返回新的字符串。

      • substring():返回一个新的字符串,包含从开始索引到结束索引之间的字符。

      • toUpperCase():将字符串中的字母转换为大写。

      • toLowerCase():将字符串中的字母转换为小写。

      • trim():去除字符串两端的空白字符。

      • split():将字符串拆分为一个字符串数组,根据指定的分隔符进行拆分。

      • replace():替换字符串中的某个子字符串为另一个字符串。

      • startsWith():检查字符串是否以指定的子字符串开头。

      • endsWith():检查字符串是否以指定的子字符串结尾。

      • includes():检查字符串是否包含指定的子字符串。

      • charAt():获取字符串中指定索引位置的字符。

      • charCodeAt():获取字符串中指定索引位置的字符的 Unicode 编码值。

      • indexOf():返回指定子字符串在字符串中第一次出现的索引位置。

      • lastIndexOf():返回指定子字符串在字符串中最后一次出现的索引位置。

ES6有哪些新特性

  1. 新增了块级作用域:let和const

  2. 箭头函数

  3. 扩展运算符和剩余参数...

  4. 解构赋值

  5. 模板字符串``

  6. 数据类型和数据结构:symbol、set、map

  7. 新增的对象、方法等,promise、proxy、Reflect等等

JS的数据类型

基本数据类型
  • 保存在栈内存中,保存的是具体的值。栈是线性数据结构

  • String、Number、Boolean、null、undefined

引用数据类型
  • 保存在堆内存中,声明一个引用类型变量时,保存的是引用数据类型的地址。堆是树形结构

  • Array、Function、Object、正则、日期等

  • 例如,声明两个引用类型同时指向了一个地址的时候,修改其中一个那么另外一个也会改变

JS对数据类型的检测方法有哪些

  • typeof():可以返回一个值的基本数据类型。只能判断基本数据类型,不能判断引用数据类型

  • instanceof():可以用来检查一个对象是否是某个构造函数的实例。只能判断引用数据类型,不能判断基本数据类型。语法例如是 'abc' instanceof String

  • constructor:检查一个对象的 constructor 属性来确定它的类型。('abc').constructor === String

  • Object.prototype.toString.call():返回一个值的详细类型信息,包括基本数据类型和对象类型。

  • Array.isArray:判断数组,如果是返回true

隐式类型转换和强制类转换

  • 强制类型转换:

    • Number():把值转换成数字

    • String():把值转换成字符串

    • Boolean():把值转换成布尔值

    • parseInt():将字符串转换为整数

    • parseFloat():将字符串转换成浮点数

    • Array.from():将类数组对象或可迭代对象转换成真正的数组

  • 隐式类型转换:js执行代码自动转换

    • 数字和字符串:+结果为字符串;-、*、/时结果为数字

    • 等号运算符比较不同的类型值,会被转换成相同的类型

    • 数字和null:null转换为0

    • 数字和undefined:undefined转换为NAN

1+‘2’ 和 1-‘2’ 的结果
  • 1+‘2’ 是“12”,做了拼接

  • 1-‘2’ 是 -1,当做减法时,js会尝试将字符串类型的2转成数值类型的2,所以就是-1

toString和String的区别

  • toString:是所有JS对象的方法,可以将任何类型的值转换为字符串。如果是null或undefined调用这个方法会输出 [object Undefined]

  • string:是一个全局函数,只能将非null和undefined值转换为字符串

let、const和var的区别

  1. 变量的作用域:

    • let和const声明的变量具有块级作用域

    • var声明的变量存在变量提升,函数级作用域

  2. 变量重复声明

    • let和const声明的变量不允许被重复声明

    • var声明的变量可以被重复声明,后面声明的覆盖前面声明的

  3. 变量的赋值

    • var和let声明的变量可以进行重新赋值

    • const声明的变量是常量,不可以进行赋值

  4. 暂时性死区:避免变量在使用前就被意外地引用或访问

    • var不存在暂时性死区

    • let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量,否则报错

const声明数组可以push元素吗?

可以的。虽然const声明的变量是常量,意味着引用是不能修改的,也就是不能将其重新赋值为另一个数组。但是可以修改数组本身的内容,进行增删改操作。

数组常见方法

  1. push(): 在数组末尾添加一个或多个元素,并返回新数组的长度。

  2. pop(): 移除并返回数组末尾的元素。

  3. unshift(): 在数组开头添加一个或多个元素,并返回新数组的长度。

  4. shift(): 移除并返回数组开头的元素。

  5. concat(): 合并两个或更多数组,并返回新的合并后的数组,不会修改原始数组。

  6. slice(): 从数组中提取指定位置的元素,返回一个新的数组,不会修改原始数组。

  7. splice(): 从指定位置删除或替换元素,可修改原始数组。

  8. indexOf(): 查找指定元素在数组中的索引,如果不存在则返回-1。

  9. lastIndexOf(): 从数组末尾开始查找指定元素在数组中的索引,如果不存在则返回-1。

  10. join(): 将数组中的所有元素转为字符串,并使用指定的分隔符连接它们。

  11. reverse(): 颠倒数组中元素的顺序,会修改原始数组。

  12. sort(): 对数组中的元素进行排序,默认按照字母顺序排序,会修改原始数组。

  13. 循环的方法:

    • filter

    • forEach

    • map

    • some

    • every

    • reduce

数组新增了哪些扩展?
  1. 扩展运算符(Spread operator):使用 ... 语法可以将一个数组展开成多个独立的元素,或者将多个元素合并为一个数组。

  2. Array.from():通过类似数组的对象或可迭代对象创建一个新的数组。

  3. Array.of():创建一个由传入参数组成的新数组。

  4. find() 和 findIndex():用于在数组中查找满足指定条件的第一个元素及其索引。

  5. includes():检查数组是否包含指定的元素,并返回布尔值。

  6. fill():使用指定的值填充数组的所有元素。

  7. flat() 和 flatMap():用于将嵌套的数组展平,减少维度。

  8. 以下方法的回调函数支持箭头函数语法。

    • filter(): 创建一个新数组,其中包含符合条件的所有元素。

    • map(): 创建一个新数组,其中包含对原始数组中的每个元素进行操作后的结果。

    • reduce(): 将数组中的元素进行累积操作,返回一个单一的值。

    • forEach(): 对数组中的每个元素执行提供的函数。

  9. entries()、keys() 和 values():用于遍历数组的键值对、键和值。

  10. 数组解构赋值:可以通过解构赋值从数组中提取值并赋给变量。

  11. 数组的扩展属性:Array.prototype.length 可以被修改,Array.prototype[@@toStringTag] 返回 "Array"

数组去重方法

  1. 使用new Set:用于存储一组唯一的值。使用new Set()将数组转为Set,再使用Array.from()转换为数组实现去重

    const res1 = Array.from(new Set(arr));
  2. for + indexOf:遍历数组,将当前元素与前面的元素进行比较,如果前面已经存在该元素,则跳过,否则将该元素添加到新数组中。

    const unique2 = arr => {
      const res = [];
      for (let i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) === -1) res.push(arr[i]);
      }
      return res;
    }
  3. filter + indexOf方法:筛选出不重复的元素,返回一个新的数组

    const unique4 = arr => {
      return arr.filter((item, index) => {
        return arr.indexOf(item) === index;
      });
    }
  4. for + includes

    const unique3 = arr => {
      const res = [];
      for (let i = 0; i < arr.length; i++) {
        if (!res.includes(arr[i])) res.push(arr[i]);
      }
      return res;
    }
  5. 两层for循环+splice

    const unique1 = arr => {
      let len = arr.length;
      for (let i = 0; i < len; i++) {
        for (let j = i + 1; j < len; j++) {
          if (arr[i] === arr[j]) {
            arr.splice(j, 1);
            // 每删除一个树,j--保证j的值经过自加后不变。同时,len--,减少循环次数提升性能
            len--;
            j--;
          }
        }
      }
      return arr;
    }

数组排序的方法

  1. sort()

    • 默认情况下,sort() 方法会将数组中的元素转换成字符串,并按照 Unicode 编码顺序进行排序。

      arr = [1,2,12,25,112]
      console.log(arr.sort()); // [1, 112, 12, 2, 25]
    • 常用方法,可以传递一个比较函数作为参数,以自定义排序方式。

      arr = [1, 2, 12, 25, 112]
      // 升序
      arr.sort(function (a, b) {
          return a - b
      })
      console.log(arr); // [1, 2, 12, 25, 112]
      ​
      // 降序
      arr.sort(function (a, b) {
          return b - a
      })
      console.log(arr); // [112, 25, 12, 2, 1]
  2. reverse():反转数组,也就是逆置

  3. 冒泡排序

    • 通过不断比较相邻的两个元素,将较大(或较小)的元素逐步向右(或向左)移动,就像气泡在水中慢慢上升一样,最终使得整个数组按照升序(或降序)排列。

      function bubblingSort(arr) {
        // 外层循环负责循环的次数。由于最后一个一定是最大的数,所以最后一个可以不用排。因此循环的次数是length - 1
        for(var i = 0; i < arr.length - 1; i++) {
          // 内层循环负责两两比较
          for(var j = 0; j < arr.length - i - 1; j++) {
            // 如果发现前一个数比后一个数大,则交换位置
            if(arr[j] > arr[j + 1]) {
              var temp = arr[j]
              arr[j] = arr[j + 1]
              arr[j + 1] = temp
            }
          }
        }
        // 返回排好序的数组
        return arr;
      }
  4. 快速排序

    • 实现原理:先从数组中随便选择一个元素(通常是数组的第0项),作为基准元素。然后循环数组,把比基准元素小的放左边,比基准元素大的放右边

      function fastSort(arr) {
        // 如果只有一个元素直接返回
        if(arr.length <= 1) return arr;
        // 假设第0个元素就是标杆
        var pivot = arr[0];
        // 声明两个数组比标杆元素小的放左边,比标杆元素大的放右边
        var left = [];
        var right = [];
        // 循环数组,比标杆元素小的放左边,比标杆元素大的放右边
        for(var i = 1; i < arr.length; i++) {
          if(arr[i] < pivot) {
            left.push(arr[i]);
          } else {
            right.push(arr[i]);
          }
        }
        // 递归调用,把比标杆元素小的放左边,比标杆元素大的放右边
        var arr2 = fastSort(left).concat(pivot, fastSort(right));
        // 改变原有数组中的元素
        for(var i = 0; i < arr2.length; i++) {
          arr[i] = arr2[i];
        }
        return arr;
      }
  5. 选择排序

    • 实现原理:

      • 遍历数组,将第一个元素设为当前最小元素。

      • 从第二个元素开始,依次与当前最小元素进行比较,找到最小的元素。

      • 将最小元素与当前位置的元素进行交换,将最小元素放置在已排序部分的末尾。

      • 重复上述步骤,每次从未排序的部分选择出一个最小元素放置在已排序部分的末尾,直到整个数组排序完成

    function selectSort(arr) {
      for(var i = 0; i < arr.length - 1; i++) {
        // 先假设第i个位置的元素是最小元素,然后保存其下标
        var minIdx = i;
        // 内层循环负责两两比较
        for(var j = i + 1; j < arr.length; j++) {
          // 如果发现有比假设的最小元素小的元素
          if(arr[j] < arr[minIdx]) {
            // 则立即更新最小位置的下标
            minIdx = j;
          }
        }
        // 交换位置
        var temp = arr[i];
        arr[i] = arr[minIdx];
        arr[minIdx] = temp;
      }
      return arr;
    }
  6. 插入排序

    • 实现原理:依次从数组中取出一个元素,然后从右向左依次查找,直到找到比它小的元素,将其插入到对应的位置

      function insertSort(arr) {
        for (var i = 1; i < arr.length; i++) {
          // 依次从数组中取出一个元素
          var curValue = arr[i];
          // 指针依次向左移动一格(即从右向左依次查找)
          var j = i - 1;
          while(j >= 0 && curValue < arr[j]) {
            // 将当前找到的元素右移一格,空出当前的位置
            arr[j + 1] = arr[j];
            j--;
          }
          // 将当前找到的元素插入到正确的位置
          arr[j + 1] = curValue;
        }
        return arr;
      }
  7. 归并排序

    • 实现原理:先对数组进行拆分,拆分到每个数组中只有一个元素则停止拆分。然后在对拆分后数组按顺序进行合并

      function mergeSort(arr) {
        // 如果数组的长度小于等于1,则直接返回
        if(arr.length <= 1) return arr;
        
        // 将数组从中间进行拆分
        var mid = Math.floor(arr.length / 2);
        // 递归拆分左边数组
        var left = mergeSort(arr.slice(0, mid));
        // 递归拆分右边数组
        var right = mergeSort(arr.slice(mid));
      ​
        // 递归进行拆分合并
        var arr2 = merge(mergeSort(left), mergeSort(right));
        // 修改原数组
        for(var i = 0; i < arr2.length; i++) {
          arr[i] = arr2[i];
        }
        return arr;
      }
      ​
      // 合并数组方法
      function merge(left, right) {
        // 先声明一个空数组
        var result = [];
        // 不断的从拆分的数组中取元素进行比较,直到其中一边没有元素为止
        while(left.length > 0 && right.length > 0) {
          // 对拆分后的数组元素进行比较,小的放左边,大的放右边
          if(left[0] <= right[0]) {
            result.push(left.shift());
          } else {
            result.push(right.shift());
          }
        }
        // 将剩余的数组元素添加到结果数组(因为比较完以后有可能左边会有剩余元素或者右边会有剩余元素)
        return result.concat(left, right);
      }
      

Array.slice() 与 Array.splice() 的区别

  • slice() 方法返回一个新数组,包含从原数组中指定的开始位置到结束位置(不包括结束位置)的元素,不会修改原数组。

    数组的截取(不包含结束位置),返回新数组,不会修改原数组

  • splice() 方法通过删除或替换现有元素或者添加新元素来修改原数组。它会返回被删除的元素组成的数组。

    删除或替换修改原数组,会返回被删除的元素组成的数组

数组中的Map和forEach的区别

  • 相同点:

    • Map和forEach都是循环遍历数组中的的每一项

    • 每次执行匿名函数都支持3个参数 (item,index,原数组)

    • 匿名函数中的this都是指向window的

  • 区别:

    • map有返回值,有映射的效果,返回一个新的数组,不改变原数组。适用于需要生成新数组,且新数组的元素是对原数组进行某种转换的情况,比如对数组中的每个元素进行计算并返回一个新数组

    • forEach没有返回值return是不起作用的,不改变原数组,只用来遍历。适用于需要遍历数组但不需要生成新数组的情况,比如在循环中执行一些操作。

      • 终止forEach可以使用try-catch抛出异常并结束循环

for...in 和 for...of的区别

  • for...in:可以用来遍历数组、对象等可迭代对象。

    • 遍历数组的话,输出的是数组元素的下标;

    • 遍历对象的话,输出的是对象的键

    // 数组
    const arr = ['a','b','c']
      for(let i in arr){
        console.log(i);
    }
    ​
    // 对象
    const obj = { a: 1, b: 2, c: 3 }
      for (let i in obj) {
        console.log(i); // 输出键名
        console.log(obj[i]); // 输出键值
    }
  • for...of:ES6引进的新特性。只能遍历数组,输出的是数组的元素

    • 不能遍历对象,因为没有interator接口

    // 数组
    const arr = ['a','b','c']
    for(let n of arr){
        console.log(n);
    }
  • 循环数组嵌套对象

    const arrObj = [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '王五' }
      ]
      for (let nObj of arrObj) {
        for (let n in nObj){
          console.log(nObj[n]); // 输出每个对象的键值
        }
    }

字符串常用方法

  1. length:返回字符串的长度。

    const str = "Hello";
    console.log(str.length); // 5
  2. charAt(index):返回指定索引位置的字符。

    const str = "Hello";
    console.log(str.charAt(1)); // e
  3. concat(string1, string2, ...):将多个字符串连接起来。

    const str1 = "Hello";
    const str2 = " World";
    console.log(str1.concat(str2)); // Hello World
  4. toUpperCase():将字符串转换为大写。

    const str = "Hello";
    console.log(str.toUpperCase()); // HELLO
  5. toLowerCase():将字符串转换为小写。

    const str = "Hello";
    console.log(str.toLowerCase()); // hello
  6. substring(startIndex, endIndex):提取从 startIndexendIndex(不包括)之间的子字符串。

    const str = "Hello World";
    console.log(str.substring(6, 11)); // World
  7. indexOf(substring, startIndex):返回指定子字符串第一次出现的索引位置。如果找不到,则返回 -1。

    const str = "Hello World";
    console.log(str.indexOf("o")); // 4
    console.log(str.indexOf("z")); // -1
  8. replace(oldValue, newValue):将字符串中的指定值替换为新值,只替换第一个匹配项。

    const str = "Hello World";
    console.log(str.replace("World", "Universe")); // Hello Universe
  9. split(separator):将字符串分割为子字符串数组,使用 separator 参数作为分隔符。

    const str = "Hello,World,Universe";
    console.log(str.split(",")); // ["Hello", "World", "Universe"]
  10. trim():去除字符串两端的空格。

    const str = "   Hello   ";
    console.log(str.trim()); // Hello
  11. startsWith(searchString, position):判断字符串是否以指定的内容开头。可选的 position 参数指定从哪个索引位置开始进行匹配。

    const str = "Hello World";
    console.log(str.startsWith("Hello")); // true
    console.log(str.startsWith("World")); // false
  12. endsWith(searchString, position):判断字符串是否以指定的内容结尾。可选的 position 参数指定从哪个索引位置结束进行匹配。

    const str = "Hello World";
    console.log(str.endsWith("World")); // true
    console.log(str.endsWith("Hello")); // false
  13. includes(searchString, position):判断字符串中是否包含指定的内容。可选的 position 参数指定从哪个索引位置开始进行匹配。

    const str = "Hello World";
    console.log(str.includes("Hello")); // true
    console.log(str.includes("Universe")); // false
  14. slice(startIndex, endIndex):提取从 startIndexendIndex(不包括)之间的子字符串。

    const str = "Hello World";
    console.log(str.slice(6, 11)); // World
  15. padStart(targetLength, padString):在字符串的开头添加指定的字符,直到字符串达到指定的长度。

    const str = "Hello";
    console.log(str.padStart(10, "X")); // XXXXHello
  16. padEnd(targetLength, padString):在字符串的末尾添加指定的字符,直到字符串达到指定的长度。

    const str = "Hello";
    console.log(str.padEnd(10, "X")); // HelloXXXX
  17. repeat(count):将字符串重复指定的次数。

    const str = "Hello";
    console.log(str.repeat(3)); // HelloHelloHello

null和undefined

console.log(typeof null) // object 表示为“无”对象0
console.log(typeof undefined) // undefined 表示“无”的原始值 NaN
(1)undefined
  1. 已经声明,未赋值

    let o;
    console.log(o)
  2. 对象某个属性不存在

    let obj = {}
    console.log(obj.a)
  3. 函数调用,少传一个参数

    function fn(a,b){
      console.log(a,b)  
    }
    fn(4)
  4. 函数的默认返回值(就是函数没有返回值的时候)

    function demo(){
        console.log("11")
    }
    console.log(demo())
(2)null
  1. 手动释放内存

    let obj = {}
    obj = null
  2. 作为函数的参数(此参数不是对象)

  3. 原型链的顶端

console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log((null == undefined)); // true
console.log((null === undefined)); // false
区别:
  1. undefined是应该有值,但是没有赋值;null表示一个空值

  2. 使用typeof判断类型的时候,undefined是undefined;null是object

null是对象吗?
  • null不是对象

  • 但是typeof null会输出“object”类型,但这是JS存在的一个bug,最初使用32位系统的时候为了性能考虑,使用的是低位存储变量的类型信息,000开头代表是对象,null表示全零,所以会误判为object。

  • 34
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值