【bug】为什么变量companyName不是Js的null值,而是字符串null

前言

最近负责人提出了这样一个需求:要求根据不同的用户,首页标题能对应改变,于是我这样做了:

login.vue

sessionStorage.setItem('companyName', res.data.companyName)

Home.vue

<template>
	<div> {{ (companyName && companyName.trim()) ? `${companyName}XXX系统` : '测试XXX系统' }} </div>
</template>

data() {
  return {
    companyName: sessionStorage.getItem('companyName'),
  };
}

但是遇到一个问题,当companyName为null时界面显示的不是【测试XXX系统】,而是【nullxxx系统】,我以为是三元表达式写的有问题,但其实是忽略了sessionStorage的用法。

一 、原因解析

sessionStorage.getItem(...)总是返回字符串,无论你之前在 sessionStorage 里存了啥,只要你用 getItem 取出来,它就是一个字符串类型,包括 nullundefinedObject 等,容易产生数据类型污染问题。

// 举例

sessionStorage.setItem('companyName', null); 
// 实际等价于 setItem('companyName', 'null')

sessionStorage.getItem('companyName'); 
// 实际等价于 "null"(字符串"null",而非 JS 的 null)

二、正确做法

必须在 setItem 和 getItem 的时候都注意类型处理,特别是排除 “null” 字符串的污染。

1.存入值时使用JSON

sessionStorage.setItem('companyName', JSON.stringify(realCompanyName));

2.读取值时使用JSON

data() {
  return {
    companyName: JSON.parse(sessionStorage.getItem('companyName')),,
  };
}

PS:当然,你也可以不用JSON,在存值时先做数据类型判断也是可以的

三、注意事项

1.undefined 这个值不能被单独用 JSON.stringify() 转换成有效的 JSON 字符串。它的结果不是 “undefined”(字符串),而是 undefined 本身(非字符串),所以不能存储或传输。

// 不确定值是否为 undefined,可以先做判断处理

const safeValue = (value === undefined) ? null : value;
sessionStorage.setItem('key', JSON.stringify(safeValue));

2.JSON.parse(“undefined”) 会抛错,JSON.parse() 只能解析合法的 JSON 字符串格式,但 “undefined” 并不是 JSON 的合法字面量。

3.只有当你存储的是通过 JSON.stringify 转换过的对象或数组等时,才需要 JSON.parse。

方法 作用
JSON.stringify() 把 JS 数据 → 转成 JSON 字符串(用于存储或传输)
JSON.parse() 把 JSON 字符串 → 还原成 JS 数据(用于读取使用)

四、封装sessionStorage存取封装函数

1.封装代码

// 工具函数文件 utils/storage.js

export const storage = {
  set(key, value) {
    if (value === undefined) return;
    sessionStorage.setItem(key, JSON.stringify(value));
  },

  get(key) {
    const raw = sessionStorage.getItem(key);
    try {
      const parsed = JSON.parse(raw);
      return parsed === 'null' || parsed === 'undefined' ? null : parsed;
    } catch (e) {
      return null;
    }
  },

  remove(key) {
    sessionStorage.removeItem(key);
  },

  clear() {
    sessionStorage.clear();
  }
};

2.使用方式

// 存值
this.companyName = '测试';
storage.set('companyName', this.companyName);

// 取值
data() {
  return {
    companyName: storage.get('companyName') || '',
  };
}