counter
请创建一个含有属性count的object。count 的初始值为0,每次取值的时候自增1。
js
const counter = createCounter()
counter.count // 0
counter.count // 1
counter.count // 2
counter.count = 100 // 无法更改
counter.count // 3题目模版
js
export default function createCounter() {}测试代码
js
// tests/createCounter.test.js
import { describe, expect, it } from 'vitest'
import createCounter from './createCounter.js'
describe('createCounter', () => {
it('首次读取 count 返回 0,之后递增:0,1,2,3...', () => {
const c = createCounter()
expect(c.count).toBe(0)
expect(c.count).toBe(1)
expect(c.count).toBe(2)
expect(c.count).toBe(3)
})
it('读取非 count 属性不应影响计数', () => {
const c = createCounter()
// 首次读取 count -> 0
expect(c.count).toBe(0)
// 读取其他不存在的属性应返回 undefined,不触发计数变化
expect(c.foo).toBeUndefined()
expect(c.bar).toBeUndefined()
// 计数应继续从 1 开始
expect(c.count).toBe(1)
})
it('设置非 count 属性应成功且不影响计数', () => {
const c = createCounter()
expect(c.count).toBe(0)
c.name = 'alice'
c.age = 20
expect(c.name).toBe('alice')
expect(c.age).toBe(20)
// 计数继续递增
expect(c.count).toBe(1)
expect(c.count).toBe(2)
})
it('直接对 count 赋值应在严格模式抛出 TypeError,且不改变计数进度', () => {
const c = createCounter()
expect(c.count).toBe(0)
expect(c.count).toBe(1)
// 模块/测试文件默认是严格模式;handler.set 对 'count' 未返回 true,会抛 TypeError
expect(() => {
c.count = 100
}).toThrow(TypeError)
// 赋值失败不应改变计数轨迹
expect(c.count).toBe(2)
expect(c.count).toBe(3)
})
it('删除 count 后再次读取应重置为 0(因为 get 会重新初始化)', () => {
const c = createCounter()
expect(c.count).toBe(0)
expect(c.count).toBe(1)
// delete 走默认行为(未定义 deleteProperty trap),会真删除目标属性
const deleted = delete c.count
expect(deleted).toBe(true)
// 删除后再次第一次读取,应重新初始化为 0
expect(c.count).toBe(0)
expect(c.count).toBe(1)
})
it('首次读取后,count 应成为目标对象自有属性(可检查 descriptor)', () => {
const c = createCounter()
// 触发创建并返回 0
expect(c.count).toBe(0)
// 现在目标对象应具备自有属性 'count'
// 由于 c 是 Proxy,直接从代理上拿 descriptor 不一定稳定;
// 但这里 Reflect.getOwnPropertyDescriptor 应该透传到 target。
const desc = Reflect.getOwnPropertyDescriptor(c, 'count')
expect(desc).toBeDefined()
expect(desc?.writable).toBe(true)
expect(desc?.enumerable).toBe(true)
expect(desc?.configurable).toBe(true)
})
it('多次交错访问与设置其它键,计数行为仍应稳定', () => {
const c = createCounter()
expect(c.count).toBe(0) // 0
c.x = 1
expect(c.y).toBeUndefined()
expect(c.count).toBe(1) // 1
c.z = { k: 9 }
expect(c.z.k).toBe(9)
expect(c.count).toBe(2) // 2
expect(c.count).toBe(3) // 3
})
})答案
| 类型 | 路径 |
|---|---|
| JS 版本 | problems/Day 23/answer.js |
| TS 版本 | 待补充 |
| Review | 待补充 |