xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

TypeScript 装饰器实现原理剖析 All In One

TypeScript 装饰器实现原理剖析 All In One

TypeScript @Decorator

function first() {
  console.log("first(): factory evaluated");
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("first(): called");
  };
}
 
function second() {
  console.log("second(): factory evaluated");
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("second(): called");
  };
}
 
class ExampleClass {
  @first()
  @second()
  method() {}
}

/*

first(): factory evaluated
second(): factory evaluated

second(): called
first(): called

*/
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
// @experimentalDecorators
function first() {
    console.log("first(): factory evaluated");
    return function (target, propertyKey, descriptor) {
        console.log("first(): called");
    };
}
function second() {
    console.log("second(): factory evaluated");
    return function (target, propertyKey, descriptor) {
        console.log("second(): called");
    };
}
class ExampleClass {
    method() { }
}
__decorate([
    first(),
    second(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ExampleClass.prototype, "method", null);

https://www.typescriptlang.org/docs/handbook/decorators.html

Object.defineProperty()

数据双向绑定,数据拦截,变化监听

const log = console.log;

const obj = {};
// Object.defineProperty(obj, prop, descriptor)
Object.defineProperty(obj, 'prop', {
  // value: undefined,
  value: 2022,
  // writable: false,
  writable: true,
  // enumerable: false,
  enumerable: true,
  // configurable: false,
  configurable: true,
  // accessors
  // get: undefined,
  // set: undefined,
});
// Error: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>
console.log(obj);

obj.prop = 2048;
// "use-strict";throws an error in strict mode

console.log(obj.prop);
// 2022


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Object.defineProperties()

const log = console.log;

const obj = {};
Object.defineProperties(obj, {
  prop: {
    value: 2022,
    writable: false,
  },
  skills: {
    value: ['TypeScript', 'JavaScript', 'HTML5'],
    writable: true,
  },
});

log(obj);
log(obj.prop);
log(obj.skills);
/*
Object {  }
2022
Array ["TypeScript", "JavaScript", "HTML5"]
*/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties

Object.getOwnPropertyDescriptor()

const log = console.log;

const obj = {
  prop: 2022,
  name: 'xgqfrms',
  skills: ['TypeScript', 'JavaScript', 'HTML5'],
};

const descriptor = Object.getOwnPropertyDescriptor(obj, 'prop');
const skills = Object.getOwnPropertyDescriptor(obj, 'skills');

log(descriptor);
// Object { value: 2022, writable: true, enumerable: true, configurable: true }
log(skills);
// Object { value: Array ["TypeScript", "JavaScript", "HTML5"], writable: true, enumerable: true, configurable: true }


log(descriptor.configurable);
log(descriptor.enumerable);
log(descriptor.writable);
// true
// true
// true

log(descriptor.value);
log(descriptor.get);
log(descriptor.set);
// 2022
// undefined
// undefined

property descriptor

A property descriptor is a record with some of the following attributes:

  1. value
    The value associated with the property (data descriptors only).

  2. writable
    true if and only if the value associated with the property may be changed (data descriptors only).

  3. configurable
    true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object.

  4. enumerable
    true if and only if this property shows up during enumeration of the properties on the corresponding object.

  5. get
    A function which serves as a getter for the property, or undefined if there is no getter (accessor descriptors only).

  6. set
    A function which serves as a setter for the property, or undefined if there is no setter (accessor descriptors only).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor

Record

Record<Keys, Type>

interface CatType {
  age: number;
  breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatType> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

cats.boris;
// ^? const cats: Record<CatName, CatInfo>

"use strict";
const cats = {
    miffy: { age: 10, breed: "Persian" },
    boris: { age: 5, breed: "Maine Coon" },
    mordred: { age: 16, breed: "British Shorthair" },
};
cats.boris;
// ^? 

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type

https://www.typescriptlang.org/play

refs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @   xgqfrms  阅读(94)  评论(6编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-02-11 SVG (viewBox) & DOM (viewport)
2020-02-11 Chrome DevTools & console & filter warning
2020-02-11 vue router & query params
2020-02-11 git 强制提交 & 覆盖 origin/master
2020-02-11 git reset & 回滚到指定的 commit & 删除历史记录
2020-02-11 git revert & git 撤销 merge
2020-02-11 git hooks & pre-commit All In One
点击右上角即可分享
微信分享提示