JS场景应用

1.JSON.parse

作用:将 JSON 格式的字符串转换为对应的 JavaScript 对象或值。

场景:后端接口会传入一大串字符串,前端需要将这些数据渲染到页面上,就要进行转换。

如:

scss 复制代码
// JSON 格式的字符串
const jsonString = '{"name":"张三","age":25,"hobbies":["读书","运动"]}';


// 接收一个符合 JSON 格式的字符串作为参数,将其转换为 JavaScript 中的对应数据类型(对象、数组、字符串、数字、布尔值或 null)
const obj = JSON.parse(jsonString);


console.log(obj.name); // 输出: "张三"
console.log(obj.age);  // 输出: 25
console.log(obj.hobbies[0]); // 输出: "读书"

如果传入的字符串不符合 JSON 格式规范,会抛出 SyntaxError 异常。

javascript 复制代码
const jsonString = '{"name":"张三", age:25}'; // 这里 age 没有用双引号

try {
  // 解析 JSON 字符串
  const obj = JSON.parse(jsonString);
} catch (error) {
  // 捕获并处理异常
  if (error instanceof SyntaxError) {
    console.error('JSON 格式错误:', error.message);
  } else {
    // 处理其他可能的异常
    console.error('发生未知错误:', error);
  }
}

用户友好方式:

javascript 复制代码
function safeParseJson(jsonString, defaultValue = {}) {
  try {
    return jsonString ? JSON.parse(jsonString) : defaultValue;
  } catch (error) {
      // 捕获并处理异常
      if (error instanceof SyntaxError) {
        console.error('JSON 格式错误:', error.message);
      } else {
        // 处理其他可能的异常
        console.error('发生未知错误:', error);
      }
    return defaultValue; // 解析失败时返回默认值
  }
}

// 使用示例
const data = safeParseJson('获取到的数据', { name: '未知用户' });

JSON.parse() 是 JavaScript 中将 JSON 字符串 "还原" 为可操作的数据结构的关键方法,是前后端数据交互和数据存储时的常用工具。

在实际开发中,接口返回的 JSON 数据可能是对象({})或数组([]),因此解析后通常需要用 Array.isArray() 判断是否为数组,再进行对应处理。

场景:JSON必须是数组格式,但是后端传入的字符串解析后的json不是数组格式。

  • JSON 格式 是一个总称,包含了对象、数组、基础类型三种表现形式。
  • JSON 数组格式 是 JSON 格式的子集,仅指用 [] 包裹的有序数据列表。

判断是否是数组,不是数组自动加入[].进行格式化显示。将数组数据带有[]展示出来。

typescript 复制代码
    let jsonData
    try {
        //解析成json
        jsonData = JSON.parse(inputValue)
        // 检查是否为数组
        if (!Array.isArray(jsonData)) {
            return new Promise((resolve) => {
                ElMessageBox.confirm(
                    '输入的JSON必须是数组格式(节点集合),是否进行格式转换?',
                    '格式错误',
                    {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'error'
                    }
                ).then(() => {
                        // 用数组包裹对象并格式化显示
                        textareaValue.value = JSON.stringify([jsonData], null, 2)
                        resolve(true);
                    }).catch(() => {
                        console.log('用户取消格式转换')
                        resolve(false)
                })
            })
        }
        return true
    } catch (e) {
        const errorMsg = e instanceof Error ? e.message : String(e)
        ElMessage.error(`输入内容不是合法的JSON格式!\n错误原因:${errorMsg}`)
        return false
    }

2.JSON.stringify()

将 JavaScript 值转换为 JSON 字符串的内置方法,对象放入一个数组中,然后转换为格式化的 JSON 字符串,最终结果会是一个包含原对象的 JSON 数组字符串。

javascript 复制代码
// 第一个参数 `[jsonData]`:要转换的 JavaScript 值(这里将 `jsonData` 包装在数组中)
// replacer 参数,为 `null` 表示转换所有可序列化的属性
// 第三个参数 `2`: space 参数,表示使用 2 个空格进行缩进,使输出的 JSON 字符串更易读

JSON.stringify([jsonData], null, 2)

jsonData是{name: "John", age: 30}

[
  {
    "name": "John",
    "age": 30
  }
]

将非数组值转为数组格式如果原始数据不是数组,但你希望输出为 JSON 数组(包裹在 [] 中),可以手动将其放入数组,这种写法会强制将结果包裹在数组中,即使原数据不是数组类型。

javascript 复制代码
 const data = { id: 1, name: "Alice" };

 // 手动包裹为数组
 const jsonArray = JSON.stringify([data], null, 2);
 console.log(jsonArray);
 // 输出:
 // [
 //   {
 //     "id": 1,
 //     "name": "Alice"
 //   }
 // ]
css 复制代码
JSON.stringify(value[, replacer[, space]])

参数说明

value(必需):要转换为 JSON 字符串的值(可以是对象、数组、字符串、数字、布尔值或 null)

replacer(可选):

diff 复制代码
-   若为函数:对每个键值对进行处理,返回值将被序列化
-   若为数组:仅包含数组中列出的属性才会被序列化
-   若为 null 或未提供:所有可序列化的属性都会被包含

space(可选):

diff 复制代码
-   用于格式化输出的缩进空格数(1-10 之间的数字)
-   若为字符串:将用该字符串作为缩进(最多前 10 个字符)
-   若为 0、null 或未提供:输出将没有缩进和空格
javascript 复制代码
  // 带格式化
  console.log(JSON.stringify(obj, null, 2));
  // 输出格式化的JSON:
  // {
  //   "name": "Alice",
  //   "age": 25,
  //   "isStudent": false
  // }
javascript 复制代码
    // 使用replacer函数过滤属性
    console.log(JSON.stringify(obj, (key, value) => {
      return key === "age" ? undefined : value; // 排除age属性
    }));
    
    {"name":"Alice","isStudent":false}
javascript 复制代码
    const numbers = [1, 2, 3, 4, 5];

    // 只保留偶数
    const evenNumbersJson = JSON.stringify(numbers, (key, value) => {
      // 注意:数组的索引会作为key,元素值作为value
      return typeof value === 'number' && value % 2 === 0 ? value : undefined;
    }, 2);

    console.log(evenNumbersJson);
    // 输出: [null, 2, null, 4, null]
    // 注意:数组空位会被转为null

3.extends 继承

extends 关键字用于实现类的继承,是 ES6(ECMAScript 2015)引入的面向对象编程特性,用于创建一个子类并继承父类的属性和方法。

scala 复制代码
    class 子类名 extends 父类名 {
      // 子类的构造函数和方法
    }

1.子类会自动获得父类中定义的所有非私有属性和方法(ES6 中通过 # 定义私有成员,子类无法直接访问)。

2.子类可以在父类基础上添加新的属性和方法,或重写(覆盖)父类的方法

3.JavaScript 不支持多继承,一个子类只能直接继承一个父类,但可以通过其他方式(如混入 mixin)实现类似多继承的效果。

scala 复制代码
 // 继承关系: A是子类(派生类),B是父类(基类)。A会自动获得B中定义的属性和方法(除了私有成员)。
 // 代码复用:通过继承,A不需要重新实现  B 中已有的功能,可以直接使用或根据需要进行重写。
// 扩展功能: A可以在B的基础上添加新的属性和方法,实现特定于自身的功能。

class A extends B
// 父类
    class B {
      constructor(name) {
        this.name = name;
      }

  // 父类的方法
  speak() {
    console.log(`${this.name} 发出声音`);
  }
}

// 子类继承父类
class A extends B {
  // 重写父类的方法
  speak() {
    console.log(`${this.name} 汪汪叫`);
  }

  // 子类新增的方法
  fetch() {
    console.log(`${this.name} 叼来了球`);
  }
}

// 使用子类
const a = new A("旺财");
a.speak(); // 输出:"旺财 汪汪叫"(调用重写后的方法)
a.fetch(); // 输出:"旺财 叼来了球"(调用子类新增方法)

super关键字:在子类的构造函数中,必须先调用 super()才能使用 this,super()用于调用父类的构造函数。

scala 复制代码
class A extends B {
  constructor(name, color) {
    super(name); // 调用父类构造函数
    this.color = color; // 子类新增属性
  }
}

4.constructor构造函数

constructor 是类被实例化(使用 new 关键字创建对象)时自动调用的方法,用于初始化实例的属性和执行初始化逻辑。

javascript 复制代码
class Person {
  // 构造函数
  constructor(name, age) {
    // 初始化实例属性
    this.name = name;
    this.age = age;
  }
  
  // 类的其他方法
  sayHello() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

// 创建实例时会自动调用 constructor
const person = new Person("Alice", 30);
person.sayHello(); // 输出: Hello, I'm Alice
arduino 复制代码
const instance = new AssignmentNode(someNodes); 
// 当通过 `new AssignmentNode(...)` 创建实例时,此时会自动调用上面的 constructor 方法

super(...) 用于调用父类的构造函数,将参数传递给父类。访问和调用父类(超类)的方法,主要在继承场景中使用。

在子类的 constructor 中,super() 用于调用父类的构造函数:

javascript 复制代码
//父类
class Animal {
  constructor(name) {
    this.name = name;
  }
  
  eat() {
    console.log(`${this.name} is eating`);
  }
}

//子类 基础父类 Animal
class Dog extends Animal {
 //new 时 接收传入值,constructor 会被自动调用。
  constructor(name, breed) {
    // 必须先调用 super() 才能使用 this
    super(name); // 调用父类的 constructor
    this.breed = breed; // 子类自己的属性
  }
  
  bark() {
    console.log(`${this.name} is barking`);
  }
}

const dog = new Dog("Buddy", "Golden Retriever");
dog.eat(); // 输出: Buddy is eating
dog.bark(); // 输出: Buddy is barking
scala 复制代码
class Cat extends Animal {
  constructor(name) {
    super(name);
  }

  eat() {
    // 调用父类的 eat 方法
    super.eat();
    console.log("Cats like fish");
  }
}

const cat = new Cat("Whiskers");
cat.eat(); 
// 输出: 
// Whiskers is eating
// Cats like fish

5.?. 被称为可选链操作符

作用是安全地访问嵌套对象的属性或方法 ,避免因中间某个属性不存在而导致的 TypeError 错误,当访问一个可能为 nullundefined 的对象的属性时,使用 ?. 可以简化判断逻辑。如果链中的某个环节为 nullundefined,表达式会直接返回 undefined,而不会抛出错误。

?. 不能用于赋值操作,例如 user?.name = "Bob" 会报错。

ini 复制代码
const user = {
  name: "Alice",
  address: {
    city: "Beijing"
  }
};

要访问 `user.address.city`,需要先判断 `user` 和 `address` 是否存在:

const city = user && user.address && user.address.city;


可选链


const city = user?.address?.city;


const user = { name: "Alice" };
const city = user?.address?.city; // undefined(不会报错)



const arr = null;
const first = arr?.[0]; // undefined



const obj = {
  func: () => "Hello"
};
const result = obj.func?.(); // "Hello"

const obj2 = {};
const result2 = obj2.func?.(); // undefined(不会报错)

6.对象解构

用于从对象或数组中提取属性 / 元素并赋值给变量。它能大幅简化代码,尤其适合处理复杂数据结构。

ini 复制代码
const user = {
  name: "张三",
  age: 25,
  gender: "男"
};

// 解构赋值
const { name, age, gender } = user;

console.log(name);   // "张三"
console.log(age);    // 25
console.log(gender); // "男"

等价于传统写法:


const name = user.name;
const age = user.age;
const gender = user.gender;


const { a, d, c } = table[index]

等价于更繁琐的写法:

const a = table[index].a;
const d = table[index].d;
const c = table[index].c;

想使用属性名作为变量名,可以用 新变量名: 原属性名

arduino 复制代码
const user = { name: "李四", age: 30 };

// 将 name 重命名为 userName,age 重命名为 userAge
const { name: userName, age: userAge } = user;

console.log(userName); // "李四"
console.log(userAge);  // 30

设置默认值

ini 复制代码
const user = { name: "王五" };

// age 不存在时,默认值为 18
const { name, age = 18 } = user;

console.log(age); // 18(因为 user.age 未定义)

解构嵌套对象

arduino 复制代码
const user = {
  name: "赵六",
  info: {
    height: 180,
    weight: 70,
    address: { city: "北京" }
  }
};

// 解构嵌套属性
const { 
  name, 
  info: { 
    height, 
    address: { city } 
  } 
} = user;

console.log(name);   // "赵六"
console.log(height); // 180
console.log(city);   // "北京"

解构函数参数

javascript 复制代码
// 传统写法
function V(user) {
  console.log(user.name, user.age);
}

// 解构写法(更简洁)
function V({ name, age }) {
  console.log(name, age);
}

V({ name: "常常", age: 1 }); // 输出:常常 1

可结合默认值使用(防止参数未传递时报错)

javascript 复制代码
// 参数默认值 + 解构默认值
function printUser({ name = "匿名", age = 0 } = {}) {
  console.log(name, age);
}

printUser(); // 输出:匿名 0(未传参时使用默认值)

数组解构

scss 复制代码
const [a, b, c] = [10, 20, 30];
console.log(a); // 10
console.log(b); // 20

// 跳过元素
const [x, , y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 3

// 剩余元素(...)
const [first, ...rest] = [1, 2, 3, 4];
console.log(rest); // [2, 3, 4]

7.includes()

适合用于简单的包含关系检测

数组中的 includes() 用法

array.includes(searchElement[, fromIndex])

  • searchElement:必需,要查找的元素

  • fromIndex:可选,开始查找的索引位置(默认从 0 开始)

    arduino 复制代码
    const fruits = ['apple', 'banana', 'orange'];
    
    // 检测是否包含 'banana'
    console.log(fruits.includes('banana')); // true
    
    // 检测是否包含 'grape'
    console.log(fruits.includes('grape')); // false
    
    // 从索引 2 开始查找 'orange'
    console.log(fruits.includes('orange', 2)); // true
    
    // 从索引 3 开始查找(超出数组长度,返回 false)
    console.log(fruits.includes('apple', 3)); // false

字符串中的 includes() 用法

string.includes(searchString[, position])

  • searchString:必需,要查找的子字符串

  • position:可选,开始查找的位置(默认从 0 开始)

    rust 复制代码
    const str = 'Hello, world!';
    
    // 检测是否包含 'world'
    console.log(str.includes('world')); // true
    
    // 检测是否包含 'foo'
    console.log(str.includes('foo')); // false
    
    // 从索引 7 开始查找 'world'
    console.log(str.includes('world', 7)); // true
    
    // 从索引 8 开始查找
    console.log(str.includes('world', 8)); // false

区分大小写

less 复制代码
['Apple', 'banana'].includes('apple'); // false(大小写不同)

对于引用类型的值(如对象),includes() 检测的是内存地址是否相同

ini 复制代码
const obj = { name: 'test' };
const arr = [obj];
console.log(arr.includes(obj)); // true
console.log(arr.includes({ name: 'test' })); // false(新对象,内存地址不同)

检测 NaN(与 indexOf() 不同,indexOf() 无法检测 NaN

arduino 复制代码
const nums = [1, 2, NaN, 4];
console.log(nums.includes(NaN)); // true
console.log(nums.indexOf(NaN)); // -1(无法检测)
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax