我们可以在打字稿声明文件中使用全局符号吗?



我正在尝试实现这样的东西,但我不确定这是否可能。 我认为 Typescript 只允许使用唯一符号,而不允许使用全局符号。 这是对的吗?

有没有更好的方法来使用全局符号?

// sample.d.ts
const mySymbol = Symbol.for('internal.symbol')
interface Sample{
[mySymbol]: string
a: number
b: number
}
// sample.js
class SampleClass implements Sample {
[mySymbol]: string
a: number
b: number
constructor(a: number, b: number){
this.a = a;
this.b = b;
this[mySymbol] = `${a}-${b}`
}
}
let mySample = new SampleClass(1, 2)

有没有办法做到这一点?mySymbol可以(理想情况下)是一个全局符号,也可以由其他对象使用,因此如果可以做到这一点,可以单独定义它。

以下是我能够做到这一点的方法。

// misc.ts
export const mySymbol = Symbol.for('internal.symbol')
// sample.d.ts
import {mySymbol} from './misc'
export as namespace Sample
export = Sample
interface Sample{
[mySymbol]: string
a: number
b: number
}
// sample.js
class SampleClass implements Sample {
[mySymbol]: string
a: number
b: number
constructor(a: number, b: number){
this.a = a;
this.b = b;
this[mySymbol] = `${a}-${b}`
}
}
let mySample = new SampleClass(1, 2)

一旦mySymbol导入到声明文件中,它就会变成一个模块。 因此,它需要专门与export = Sample一起导出export as namespace Sample. 请参阅示例模块.d.ts。

您可以导出您的符号,即

export const mySymbol = Symbol.for('internal.symbol')

然后将其导入到需要它的任何文件中。这样您就不会污染全局范围,并且只能在必要时导入它。

...我认为 Typescript 只允许使用唯一符号,而不允许使用全局符号。这是对的吗?

所有符号都是唯一的。 这是不变的。

如何确定符号的范围和访问是另一个问题。

有两种方法可以创建符号:

第一种方式Symbol(mnemonic?:string),例如

const x = Symbol('optional name')
const y = Symbol('optional name')
assert(x!==y) // pass

每次调用Symbol(...)都会创建一个独特的符号。mnemonic只是调试等的便利属性。 两个符号可以具有相同的助记符,但不是相同的符号。

console.log(x.toString()) // 'Symbol(optional name)'
assert(x.toString()===y.toString()) // pass
assert(x!==y) // pass

当以这种方式创建符号时,它们只有在用户代码中被引用时才存在 - 就像其他对象一样,它们可以被垃圾回收。

第二种方式Symbol.for(globalKey:string),例如

在文件"x.js"中,根本没有import/require语句

const x = Symbol.for('my.global.symbols.1')
export x

在文件"y.js"中,根本没有import/require语句

const x = Symbol.for('my.global.symbols.1')
export y

在文件"z.js"中

import {x} from './x'
import {y} from './y'
assert(x===y) // pass
const z = Symbol.for('my.global.symbols.1')
assert(x===z) // pass

在这种情况下,将为作为globalKey参数传递到Symbol.for(globalKey:string)的每个 UNIQUE 全局键创建一个唯一的全局符号 - 从任何文件。 符号实例存储在不透明的全局空间中,就好像有一个不透明的全局映射一样:

Symbol.for(globalKey:string):symbol{
if (globalSymbolMap.has(globalKey)
return globalSymbolMap.get(globalKey)
else{
const s=Symbol(globalKey)
globalSymbolMap.set(globalKey,s)
return s
}
}

(尽管这可能不是它实际实现的方式)。

以下是MDN对Symbol.for()的评价:

与 Symbol(

) 相反,Symbol.for() 函数创建一个在全局符号注册表列表中可用的符号。Symbol.for() 也不一定在每次调用时创建一个新符号,但首先检查注册表中是否已经存在具有给定键的符号。在这种情况下,将返回该符号。如果没有找到具有给定键的符号,Symbol.for() 将创建一个新的全局符号。

关于这些全局管理的符号的垃圾回收 -我不知道以下哪项是正确的:

  • 当全局管理的符号不再被任何用户代码引用时(即,不包括来自不透明全局"虚拟"映射的引用),那么它可能会被垃圾回收。

  • 创建后,全局管理的符号将保留在不透明的全局"虚拟"映射中,直到程序生命周期结束。

从用户代码"逻辑"的角度来看,两者之间没有区别 - 这完全是一个实现问题。 但是,性能(包括内存使用情况)会有所不同。 我的猜测是启用了一些垃圾收集。

相关内容

  • 没有找到相关文章

最新更新