您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > javascript

JavaScript 中的 Symbol 大揭秘

时间:2023-04-11 13:33:20  来源:今日头条  作者:Echa攻城狮

大家好,我是Echa。

上个月有部分前端友友私信小编咨询 JAVAScript 中 Symbol 怎么使用的呢?在哪些应用场景下会用到这个Symbol?有哪些内置属性?等等。问的问题五花八门,今天无意中翻到《JavaScript 权威指南》这本书集中有几页详细解读——Symbol 。

 

所以小编决定出一期关于Symbol 读后感的文章来深入解读它。闲话少说,直接进入主题。

全文大纲

  1. Symbol 前身
  2. Symbol 介绍
  3. Symbol 使用注意事项
  4. Symbol 的应用场景
  5. Symbol 名下哪些属性?

Symbol 前身

ES5的对象属性名都是字符串,这很容易造成属性名的冲突。 比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入的Symbol的原因。

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

在JavaScript诞生之初,对象属性只能使用字符串作为键,这导致了一些问题。例如,当两个不同的对象试图使用相同的字符串作为属性名时,可能会导致属性名冲突。此外,JavaScript中没有一种简单的方法来实现私有属性或方法。

其实对于Symbol的追溯早在Lisp语言中就有体现:

(setq e (intern "echa-symbol"))

这里其实就是创建了一个名为 echa-symbol 的符号对象,并将其赋值给变量e。

另外,ES6引入Symbol其实离不开Ruby的身影,在Ruby中,可以使用冒号(:)来创建符号。冒号后面跟着符号的名称,如:

:echa-symbol

可以看到其实Ruby的语法更加简洁,定义和使用都是用冒号区分:

person = {
  'name' => 'Echa',
  'age' => 35,
  :gender => 'Male'
}
puts person[:gender]  # 输出:'Male'

所以,在这样的需求背景下,ES6在首批特性中包含了Symbol也不足为奇了。

Symbol 介绍

Symbol是ES6中新增的一种原始数据类型, 被划分到了基本数据类型中基本数据类型: 字符串、数值、布尔、undefined、null、Symbol 引用数据类型: Object。

例如 number, boolean或者null,它们通常用于避免属性名称冲突,或模拟 JavaScript 对象的私有值。

您可以通过调用全局函数来创建 Symbol():

const sym = Symbol();

Symbol() 函数接受一个参数,一个字符串 description 打印 Symbols 时会显示。

const sym = Symbol('my description');
console.log(sym); 
// Prints "Symbol(my description)"

主要特征

Symbols 有两个关键特征。

第一个关键特征是 没有两个 Symbols 永远相等 。 即使两个 Symbols 具有相同的描述,它们也不相等。

let s1 = Symbol('foo');
let s2 = Symbol('foo');

console.log(s1 === s2)
//false

第二个关键特性是 对象键可以是 Symbols。通常对象键只能是 Symbols 或字符串。

const test = Symbol('test');
const obj = {};
obj.test = 'hello';
obj[test] = 'world';
obj.test;
// 'hello'obj[test];
// 'world'

由于没有两个 Symbols 永远相等,因此除非您有权访问 Symbols,否则您无法访问 Symbols 属性。 这使得 Symbols 可以方便地创建只能在特定函数中访问的隐藏值。

function addSymbol(obj) {  
  const sym = Symbol('test'); 
  obj[sym] = 'my hidden value'; 
  return obj;
}
const obj = addSymbol({});
// No way to access obj[sym] here, unless you explicitly look
// into `Object.getOwnPropertySymbols()`.

Symbols 也被排除在外JSON.stringify()输出,这使得它们非常适合存储最终用户不应该看到的纯程序数据。

Symbol 值最显著的用途是作为对象属性的 key。而 ES6 之前,属性的 key 只能是字符串(否则也会发生自动类型转换)。key 为 Symbol 值的属性无法使用点号(.)访问,只能使用中括号([])。类似地,在对象字面值或类定义中,添加 key 为 Symbol 值的属性需要借助计算属性名的语法,如:

const MY_KEY = Symbol();
const FOO = Symbol();
let obj = {
    [MY_KEY]: 123,
    [FOO]() {
        return 'bar';
    }
}; 

JavaScript 模块化后,在模块中创建 Symbol 值并用作对象属性 key,模块作者可以自信地认为该属性不会覆写对象上已有的属性。类似道理,如果模块中使用了 Symbol key 的对象属性,只要不把 Symbol 值导出,就可以确信其他模块不会不经意地覆写该属性。

对于应用开发者,Symbol 可以有这样的使用场景:你从某第三方代码获得了一个对象,你想在该对象上存储自己的属性,但该第三方代码是不透明的,或者不受你控制,所以你无从得知第三方代码会在该对象上设置什么属性,此时就可以使用 Symbol key 属性,既能确信不会和已有属性冲突,也能确信第三方代码不会意外地修改你设置的属性:

const extension = Symbol('my extension symbol');
let o = {
    [extension]: {/* 将扩展数据存储于该对象*/}
};
o[extension].x = 0; // 无论怎样都不可能和 o 的其他属性产生冲突。

以上场景还可表述为给对象关联一个值,但存储关联值的键名希望从机制上防止和其他属性名冲突。另外也可用 WeakMap 存储对象到其关联值的映射,两种方法的异曲同工之处是:当对象本身消亡时,该映射关系也随之消亡。

然而,必须知道的是,Symbol key 属性并不是一种安全机制,第三方代码仍然可以调用
Object.getOwnPropertySymbols(o) 获得对象上的 Symbol key 属性,改变属性值,但此时就是第三方库有意为之,而不是不经意的行为了,但这应该会在其文档上有所提及才对。

Symbol 使用注意事项

  • Symbol是基本数据类型!!!!不要加new哦
  • 后面括号可以传入一个字符串,只是一个标记,方便我们阅读,没有任何意义
  • 类型转化的时候不可转化为数值
//只能转化为字符串和布尔值
console.log(String(name));
console.log(Boolean(name));
console.log(Number(name))
  • 不能做任何运算
let name=Symbol('Echa');
console.log(name+111)
console.log(name+'ccc')
//全部报错
  • symbol生成的值作为属性或者方法的时候,一定要保存下来,否则后续无法使用
let name=Symbol('name');
let obj={
  // name:'lnj',
    [Symbol('name')]:'lbj'
}
console.log(obj.name);  
//访问不到,因为  [Symbol('name')]又是一个新的值,和上面的name不是同一个
  • for循环遍历对象的时候是无法遍历出symbol的属性和方法的 Object.getOwnPropertySymbols()
et name=Symbol('name');
let obj={
  [name]:'lnj',
    age:12,
    teacher:'wyx'
}
for(let key in obj){
    console.log(key)   //只能打印出age和teacher
}
//这个方法可以单独取出Symbol(name)
console.log(Object.getOwnPropertySymbols(obj))

 

Symbol 的应用场景

  • 在企业开发中如果需要对一些第三方的插件、框架进行自定义的时候可能会因为添加了同名的属性或者方法, 将框架中原有的属性或者方法覆盖掉为了避免这种情况的发生, 框架的作者或者我们就可以使用Symbol作为属性或者方法的名称。
  • 消除魔术字符串

魔术字符串:在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。

const gender = {
   //这样就说明man就是一个独一无二的值,不用再man:'man'   
    man: Symbol(),
    woman: Symbol(),
}
function isMan(gender) {
    switch (gender) {
        case gender.man:
            console.log('男性');
            break;
        case gender.woman:
            console.log('女性');
            break
    }
}
isMan(gender.man)  //男性
  • 为对象定义一些非私有的、但又希望只用于内部的方法。

由于以 Symbol 值作为键名,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。

注意:symbol并不能实现真正的私有变量的效果,只是不能通过常规的遍历方法拿到symbol类型的属性而已

再来复习一下对象的遍历方法

  1. for (let xx in obj) :i代表key
  2. for (let xx of obj):不是自带的哈
  3. Object.keys(obj) :返回包含key的数组
  4. Object.values(obj) :返回包含value的数组
  5. Object.getOwnPropertyNames() :返回包含key的数组

上述的所有方法都是遍历不到symbol类型的(注意,是遍历时取不到symbol,并不是说我们访问不到对象的symbol类型)

可以遍历到symbol的方法:


Object.getOwnPropertySymbols() :返回对象中只包含symbol类型key的数组

Reflect.ownKeys() :返回对象中所有类型key的数组(包含symbol)

let _password = Symbol('password')
const obj = {
    name: 'Echa',
    gender: 'male',
    [_password]: '123456'
}
for (let item in obj) {
    console.log(item);
}
console.log(Object.keys(obj));
console.log(Object.values(obj));
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));
console.log(Reflect.ownKeys(obj))
// 输出123456,所以还是可以直接访问到symbol类型的属性,
//所以symbol并不能真正实现私有变量的设定,
//所以一般只用于定义一些非私有的、但又希望只用于内部的方法
console.log(obj[_password]);

Symbol 名下哪些属性?

在 JavaScript 中,Symbol 是一种非常特殊的数据类型,可以用来表示独一无二的值。每个 Symbol 值都是唯一的,一般可以作为对象属性的标识符使用,这些属性称为 Symbol 属性,它们不会与其他属性产生命名冲突,所以可以用于实现一些高级特性和语言扩展。

Symbol 还有一些内置属性,比如 Symbol.iterator、Symbol.toPrimitive 和 Symbol.toStringTag 等,它们在实现一些特殊的需求(比如自定义对象的迭代、类型转换和字符串描述时)非常有用,今天我们就来一起看一下 Symbol 内置属性的一些妙用,看看你知道几个?

Symbol.iterator

Symbol.iterator 可以让我们定义一个对象默认的迭代器。

有什么用途呢?正常的对象一般都是不可迭代的,如果我们直接用 for of 遍历一个对象,会抛出异常:TypeError: obj is not iterable ,因为对象默认是不可迭代的。

我们可以用 for in 来做遍历:

const obj = { name: 'ConardLi', age: 17 };

for (const key in obj) {
  if (Object.hasOwnProperty.call(obj, key)) {
    const element = obj[key];
    console.log(key, element);
  }
}

但是如果我们开发的是一个自定义的数据结构,for in 可能就不那么好使了,比如现在有一个音乐播放器对象,我们需要实现一个自定义的播放列表,用于存储用户添加的歌曲。这个列表可以看作一个集合,其中每个元素代表一个歌曲,包含歌曲的名称、作者、时长等属性。

这时我们就可以通过定义 Symbol.iterator 方法,让这个列表可以通过 for...of循环进行遍历:

class Song {
  constructor(name, artist, duration) {
    this.name = name;
    this.artist = artist;
    this.duration = duration;
  }
}

class Playlist {
  constructor() {
    this.songs = [];
  }

  addSong(song) {
    this.songs.push(song);
  }

  [Symbol.iterator]() {
    let index = 0;
    const songs = this.songs;
    return {
      next: () => ({
        value: songs[index++],
        done: index > songs.length
      })
    }
  }
}

const playlist = new Playlist();

playlist.addSong(new Song('Song 1', 'Artist 1', '3:45'));
playlist.addSong(new Song('Song 2', 'Artist 2', '4:20'));
playlist.addSong(new Song('Song 3', 'Artist 3', '5:10'));

for (const song of playlist) {
  console.log(song.name);
}

// 输出:
// "Song 1"
// "Song 2"
// "Song 3"

Symbol.toStringTag

默认情况下,我们在任何一个自定义的对象上调用 toString 方法,返回值都是下面这样:

[object Object]

Symbol.toStringTag 可以被用来自定义对象的 toString 方法的返回值(注意不是重写 toString 方法),这个特性在调试的时候非常有用,帮助开发者更方便地了解对象的类型信息:

class People {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  get [Symbol.toStringTag]() {
    return 'People';
  }
}

const people = new People('ConardLi', 17);

console.log(people.toString()); // [object People]

Symbol.toPrimitive

Symbol.toPrimitive 可以被用来自定义对象类型转换时的行为。它可以接受一个 hint 参数,用于指示对象应该被转换成什么类型的值,比如 Number、String 或者其他默认的值。

举一个实际的应用场景:假设我们正在开发一个日期处理工具,其中需要实现一个自定义的日期时间对象。这个对象包含日期时间的年月日时分秒等信息,这时候就可以用到 Symbol.toPrimitive 方法,来帮助我们自定义对象的类型转换行为:

class MyDateTime {
  constructor(year, month, day, hour = 0, minute = 0, second = 0) {
    this._datetime = new Date(year, month - 1, day, hour, minute, second);
  }

  [Symbol.toPrimitive](hint) {
    switch (hint) {
      case 'number':
        return this._datetime.getTime();
      case 'string':
        return this._datetime.toLocaleString();
      default:
        return this._datetime.toString();
    }
  }
}

const myDate = new MyDateTime(2023, 4, 8, 15, 30, 0);

console.log(myDate); // 输出:Sat Apr 08 2023 15:30:00 GMT+0800 (中国标准时间)
console.log(myDate + 10000); // 输出:1699950200000
console.log(`${myDate}`); // 输出:"2023/4/8 下午3:30:00"

Symbol.asyncIterator

Symbol.asyncIterator 可以用来实现一个对象的异步迭代器,它可以用于遍历异步数据流,比如异步生成器函数、异步可迭代对象等。这个特性在我们需要处理异步数据流时非常有用。

举一个实际的应用场景:假设我们正在开发一个异步数据源处理器,其中包含了大量的异步数据,比如网络请求、数据库查询等。这些数据需要被逐个获取并处理,同时由于数据量非常大,一次性获取全部数据会导致内存占用过大,因此需要使用异步迭代器来逐个获取数据并进行处理:

class AsyncDataSource {
  constructor(data) {
    this._data = data;
  }

  async *[Symbol.asyncIterator]() {
    for (const item of this._data) {
      const result = awAIt this._processAsyncData(item);
      yield result;
    }
  }

  async _processAsyncData(item) {
    // 模拟异步处理数据的过程
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(item.toUpperCase());
      }, Math.random() * 1000);
    });
  }
}

async function processData() {
  const dataSource = new AsyncDataSource(['a', 'b', 'c', 'd', 'e']);
  for await (const data of dataSource) {
    console.log(data);
  }
}

processData();

Symbol.hasInstance

Symbol.hasInstance可以用于确定一个对象是否是某个构造函数的实例,它可以用来改变 instanceof 的行为:

class MyArray {
  static [Symbol.hasInstance](instance) {
    return Array.isArray(instance);
  }
}

const arr = [1, 2, 3];
console.log(arr instanceof MyArray); // true

Symbol.species

Symbol.species 可以用于指定创建派生对象时要使用的构造函数。一个实际的需求场景可能是我们需要对一个类进行继承,并且希望这个类的某些方法返回一个新的派生对象而不是基类的实例对象。下面是一个简单的例子:

class MyArray extends Array {
  static get [Symbol.species]() {
    return Array;
  }

  test(){
    console.log('test');
  }
}

const myArray = new MyArray(1, 2, 3);
const mAppedArray = myArray.map(x => x * 2);
myArray.test();

console.log(mappedArray instanceof MyArray); // false
console.log(mappedArray instanceof Array); // true

Symbol.match

Symbol.match 可以用来确定使用 String.prototype.match 方法时要搜索的值,它可用于更改 match 类 RegExp 对象的方法行为,下面是一个实际实用案例:

class CustomRegExp extends RegExp {
  [Symbol.match](str) {
    const matches = super[Symbol.match](str);
    if (matches) {
      return matches.map(match => {
        return `匹配到了: ${match}`;
      });
    }
    return matches;
  }
}

const regex = new CustomRegExp('hello', 'g');
const result = 'hello world'.match(regex);
console.log(result); // ["匹配到了: hello"]

Symbol.replace

Symbol.replace 可以帮我们更灵活的处理 String.prototype.replace 方法,比如我们可以自定义字符串的替换行为。

比如有这样一个需求场景:我们有一个字符串处理库,我们想自定义它的 replace 方法,让它可以替换一个字符串的所有元音字母。这时候就可以用到 Symbol.replace :

const vowels = ['a', 'e', 'i', 'o', 'u'];

const customReplace = str => {
  let result = '';
  for (let i = 0; i < str.length; i++) {
    if (vowels.includes(str[i])) {
      result += '*';
    } else {
      result += str[i];
    }
  }
  return result;
};

const customString = {
  [Symbol.replace]: customReplace
};

const originalString = "hello world";

const result = originalString.replace(customString, '');

console.log(result); // outputs "h*ll* w*rld"

Symbol.split

Symbol.split 可以用来确定使用 String.prototype.split 方法执行时具体要拆分的值。

一个实际需求场景:我们需要从文本中提取出所有的数字。但是文本中的数字可能包含在不同的字符和符号中,例如括号、分隔符和单位等。使用 Symbol.split 可以自定义分割符,这样我们就可以根据自己的需求来对文本进行分割。

const customSplit = str => str.split(/[s$¥€]+/);

const customRegExp = {
  [Symbol.split]: customSplit
};

const string = "100$200¥300€400 500";

console.log(string.split(customRegExp)); // outputs [ '100', '200', '300', '400', '500' ]

Symbol.unscopables

Symbol.unscopables 通常可以用来避免在使用 with 语句时访问对象中不希望被访问的属性。下面是一个示例,其中使用 with 语句访问对象的某些属性,但通过将这些属性添加到 [Symbol.unscopables] 对象中,可以防止访问:

const globalVars = {
  a: 10,
  b: 20,
  [Symbol.unscopables]: {
    b: true
  }
};

with (globalVars) {
  console.log(a); // 输出 10
  console.log(b); // 抛出 ReferenceError
}

最后

一台电脑,一个键盘,尽情挥洒智慧的人生;几行数字,几个字母,认真编写生活的美好;

一 个灵感,一段程序,推动科技进步,促进社会发展。

创作不易,喜欢的老铁们加个关注,点个赞,打个赏,后面会不定期更新干货和技术相关的资讯,速速收藏,谢谢!你们的一个小小举动就是对小编的认可,更是创作的动力。



Tags:JavaScript   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  Search: JavaScript  点击:(5)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  Search: JavaScript  点击:(27)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  Search: JavaScript  点击:(20)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  Search: JavaScript  点击:(2)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  Search: JavaScript  点击:(2)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06  Search: JavaScript  点击:(53)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  Search: JavaScript  点击:(68)  评论:(0)  加入收藏
使用 JavaScript 清理我的 200GB iCloud,有了一个意外发现!
本文作者在综合成本因素之下,决定用 Java 脚本来清理一下自己的 iCloud,结果却有了一个意外发现,即在 iCloud 中上传同一个视频和删除此视频之后,iCloud 的空间并不一致,这到底是...【详细内容】
2024-01-11  Search: JavaScript  点击:(99)  评论:(0)  加入收藏
JavaScript前端框架2024年展望
Angular、Next.js、React和Solid的维护者和创作者们展望2024年,分享了他们计划中的改进。译自2024 Predictions by JavaScript Frontend Framework Maintainers,作者 Loraine...【详细内容】
2024-01-05  Search: JavaScript  点击:(91)  评论:(0)  加入收藏
JavaScript开发者转向Rust的原因?
JavaScript开发者转向Rust的原因可能有很多,这里列出一些可能的原因: 性能: Rust是一种编译型语言,其性能通常优于JavaScript等解释型语言。对于需要处理大量数据或需要高并发的...【详细内容】
2024-01-04  Search: JavaScript  点击:(99)  评论:(0)  加入收藏
▌简易百科推荐
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  前端新世界  微信公众号  Tags:JavaScript   点击:(5)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  前端新世界  微信公众号  Tags:JavaScript   点击:(27)  评论:(0)  加入收藏
又出新JS运行时了!JS运行时大盘点
Node.js是基于Google V8引擎的JavaScript运行时,以非阻塞I/O和事件驱动架构为特色,实现全栈开发。它跨平台且拥有丰富的生态系统,但也面临安全性、TypeScript支持和性能等挑战...【详细内容】
2024-03-21  前端充电宝  微信公众号  Tags:JS   点击:(25)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  前端历险记  微信公众号  Tags:JavaScript   点击:(20)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  WangLiwen    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  京东云开发者    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06    51CTO  Tags:JavaScript   点击:(53)  评论:(0)  加入收藏
JS小知识,使用这6个小技巧,避免过多的使用 if 语句
最近在重构我的代码时,我注意到早期的代码使用了太多的 if 语句,达到了我以前从未见过的程度。这就是为什么我认为分享这些可以帮助我们避免使用过多 if 语句的简单技巧很重要...【详细内容】
2024-01-30  前端达人  今日头条  Tags:JS   点击:(56)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  南城大前端  微信公众号  Tags:JavaScript   点击:(68)  评论:(0)  加入收藏
使用 JavaScript 清理我的 200GB iCloud,有了一个意外发现!
本文作者在综合成本因素之下,决定用 Java 脚本来清理一下自己的 iCloud,结果却有了一个意外发现,即在 iCloud 中上传同一个视频和删除此视频之后,iCloud 的空间并不一致,这到底是...【详细内容】
2024-01-11    CSDN  Tags:JavaScript   点击:(99)  评论:(0)  加入收藏
站内最新
站内热门
站内头条