前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解装饰器是怎么使用的

理解装饰器是怎么使用的

作者头像
小丑同学
发布2020-09-21 10:54:53
6250
发布2020-09-21 10:54:53
举报
文章被收录于专栏:小丑的小屋

前言

js 和 ts 中经常看到@+函数名的字样这个就是装饰器。它可以修饰类,类的属性,类的原型上的方法,说的简单一点它就是一个函数,可以传递参数在修饰的时候把这个类的属性传递给修饰的函数。

代码语言:javascript
复制
@flag("帅")
class Animal{
    @readOnly
    age = 18
    constructor(){
        this.name = '小丑'
    }
    @before
    address(){
        console.log(this);
        console.log("小丑的小屋");
    }
}

配置环境

装饰器还不被浏览器解析,需要通过babel来转化之后才行。

我们需要借助@babel/cli[1]来编译文件

安装@babel/cli最好是安装到本地项目中,通过npx来启动babel去编译,不要全局安装@babel/cli到本机上,会有不同版本babel的问题,被坑哭了

npxnode提供的,可以帮助我们执行.bin目录下的文件

需要安装的插件

代码语言:javascript
复制
npm install  @babel/core @babel/cli -D

npm install @babel/preset-env -D

npm install  @babel/plugin-proposal-class-properties -D 主要作用是用来转化类的属性的

npm install  @babel/plugin-proposal-decorators -D

需要配置的文件.babelrc

代码语言:javascript
复制
{
    "presets":[   //预设包
        "@babel/preset-env"
    ],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose" : true }]
    ]
}

编译命令

代码语言:javascript
复制
npx babel xxx.js -o xxx.js

修饰类的静态属性

代码语言:javascript
复制
function flag(){
    console.log(arguments);
}
代码语言:javascript
复制
function flag(custructor){
   custructor.type="帅"
}
console.log(Animal.type)   //❌这个写法是错误的

编译后的 es5

代码语言:javascript
复制
"use strict";

var _dec, _class, _temp;

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

var Animal =
  ((_dec = flag()),
  _dec(
    (_class =
      ((_temp = /*#__PURE__*/ (function () {
        function Animal() {
          _classCallCheck(this, Animal);

          this.age = 18;
          this.name = "小丑";
        }

        _createClass(Animal, [
          {
            key: "address",
            value: function address() {
              console.log(this);
              console.log("小丑的小屋");
            },
          },
        ]);

        return Animal;
      })()),
      _temp))
  ) || _class);

function flag(custructor) {
  custructor.type = "帅";
}

console.log(Animal.type);

抽取代码之后是一个自执行函数,传入返回的构造函数之后执行

装饰器函数可以改造为:

代码语言:javascript
复制
function flag(value){
    return function(custructor){
       custructor.type = value
    }
}
console.log(Animal.type);  //✔  帅

修改类的属性(实例上的属性)

代码语言:javascript
复制
function readOnly(target,prototype,descriptor){
    console.log(arguments)
    descriptor.writable = false;
    console.log(arguments);
    setTimeout(()=>{
       console.log(target == Animal.prototype);  //类的原型
       console.log(Animal.prototype);  //{constructor: ƒ, address: ƒ}
       console.log(Animal.prototype.constructor);
    })
}

let a= new Animal();
console.log(a.age)  //18
代码语言:javascript
复制
a.age =19
console.log(a.age)   //❌  read only

修改原型上的方法

代码语言:javascript
复制
function before(target,prototype,descriptor){
    console.log(arguments)
    let oldSay = descriptor.value;
    descriptor.value = function(){
        console.log('before');
        console.log(...arguments);
        oldSay.call(target,...arguments)
    }
    //console.log(descriptor);
}
let a= new Animal();
a.address()  //小丑的小屋

执行结果:

参考资料

[1]babel-cli: https://www.babeljs.cn/docs/babel-cli

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小丑的小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 配置环境
  • 修饰类的静态属性
  • 修改类的属性(实例上的属性)
  • 修改原型上的方法
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档