6.28学习 babel转换,es6的装饰器

news/2024/7/11 1:39:16 标签: 学习, es6, 前端

6.28学习 babel转换,es6的装饰器

  • 1.babel转换
    • 1.1出现问题
    • 1.2babel转换
  • 2.装饰器
    • 2.1类装饰器
    • 2.2方法装饰器

1.babel转换

1.1出现问题

先来一段代码,运行,有可能是会报错的,为什么呢?因为JS以前只能运行在浏览器中,Node.js 出现之后,不管是服务器上,还是我们自己的的笔记本上,只要安装了 Node.js 就可以运行 JS 代码了。所以是node帮我们运行了代码的。
有可能报错的原因是node的版本很多,这种很新的语法可能在低版本的node版本是不支持的。

class Animal{
   static flag = '哺乳类';
   constructor(){
      this.name = 'XXX'
   }
   say(){
      console.log('say')
   }
}
let animal1 = new Animal();
console.log(animal1,Animal.flag)
animal1.say()

目前我的node版本是14.15.1,是可以支持的
在这里插入图片描述
但是我把node的版本降为8.17.0的话,就会报错的
在这里插入图片描述
我们下面就以8.17.0的版本演示下面的内容。

1.2babel转换

如果版本不支持的话,我们就可以用babel/将我们的高级代码(es7等)转换为es5代码。这里就要装一个包babel-cli。但是babel-cli是以前的写法了,现在一般是@babel/cli。执行命令:

npm init  npm install @babel/cli --dev

安装后会发现在node_modules目录下多一个.bin目录
在这里插入图片描述
这里再引入一个 npx命令,它是node5.2版本以上会提供的,帮我们执行node_modules/.bin目录下的文件。那我们执行下 npx babel试一下
在这里插入图片描述
看到报错了,未找到@babel/core模块。那我们再npm install @babel/core --dev把它装上后再试一下npx babel
在这里插入图片描述
还是报错,语法不对这里是。要告诉它编译的是哪个文件和编译后要变成什么文件。
在这里插入图片描述
会发现确实目录下多了个编译后的文件,我这里是es5.js。但是打开一看发现,跟原来编译前的代码一摸一样!!!那不是没编译嘛。
其实是 @babel/core只做转换的动作,但是你还需要告诉它转换的规则是什么。这里就要在你项目的最外层,和node_modules同级目录建一个.babelrc文件。
我们下载包@babel/preset-env,并且在.babelrc中配置

{
   "presets": ["@babel/preset-env"],
   "plugins": []
}

然后再执行我们的npx命令(我的是npx babel .\index.js -o ./es5.js),发现编译出来的文件不一样了!!!

在这里插入图片描述
再运行
在这里插入图片描述
但是这个@babel/preset-env包也只能转换已定案的语法,像更高级的语法,例如装饰器,static xxx = 'xx’等还是无法转译的。
@babel/plugin-proposal-class-properties 这个包就是用来转换static xxx = ‘xx’(类的属性的) 不支持的话可以安装。
其实npx的执行顺序可以看作 @babel/cli ==> @babel/core ==> 转换(读取.babelrc中的配置)

2.装饰器

2.1类装饰器

装饰器写在类外面的是类装饰器

//装饰器 mobx nest vue 
//装饰器可以修饰 类的属性 类的原型上的方法
//修饰的时候就是把这个类 属性... 传递给修饰的函数
@flag
class Animal{
   // static flag = '哺乳类';
   name = 'XXX'
   say(){
      console.log('say')
   }
}

function flag(Constructor){
   Constructor.type = '哺乳类'
}
console.log(Animal.flag)

类装饰器有个参数,就是会被装饰的类
这里执行npx命令就会报错
在这里插入图片描述
他还给了提示,那我们就把@babel/plugin-proposal-decorators装上,并且在.babelrc中配置

{
   "presets": ["@babel/preset-env"],
   "plugins": ["@babel/plugin-proposal-decorators"]
}

再来npx,还是报错。。。
在这里插入图片描述
,babelrc配置写错了

{
   "presets": ["@babel/preset-env"],
   "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }]
   ]
}

再npx可以的了
上面的装饰器是可以传参的,例如

@flag('哺乳类')
function flag(value){
   return function (Constructor) {
      Constructor.type = value
   }
}

其实@flag可以看成个语法糖

@@flag('哺乳类')
flag('哺乳类')(Animal)
function flag(value){
   return function (Constructor) {
      Constructor.type = value
   }
}

2.2方法装饰器

写在类里面的装饰器就是方法装饰器,他有三个参数的。第一个参数是类的原型对象,上例是Animal.prototype,装饰器的本意是要“装饰”类的实例,但是这个时候实例还没生成,所以只能去装饰原型(这不同于类的装饰,那种情况时target参数指的是类本身);第二个参数是所要装饰的属性名,第三个参数是该属性的描述对象。

@flag
class Animal{
   // static flag = '哺乳类';
   @readonly
   name = 'XXX'
   say(){
      console.log('say')
   }
}

function flag(Constructor){
   Constructor.type = '哺乳类'
}
console.log(Animal.type)

//直接编译会出错的 npx babel .\class-decorator.js -o es5.js

//1)类的静态属性

//2)类的属性(实例上的属性)

// function readonly() {
//    console.log(arguments)//有三个参数 Animal的实例 属性 配置项({
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: [Function: initializer]
})
// }
function readonly(target,property,descriptor) {
   console.log(target == Animal.prototype)
}

所以把这段代码编译后执行会报错,
在这里插入图片描述
因为这个时候实例还没生成,这样写就不会报错

  setTimeout(function () {
    console.log(target == Animal.prototype);
  });

方法装饰器可以修改属性的描述对象(descriptor),然后被修改的描述对象再用来定义属性。
我们在方法前面定义一个装饰器,它的第三个参数是不一样的

//装饰器 mobx nest vue 
//装饰器可以修饰 类的属性 类的原型上的方法
//修饰的时候就是把这个类 属性... 传递给修饰的函数
@flag
class Animal{
   // static flag = '哺乳类';
   @readonly
   name = 'XXX'
   @before
   say(){
      console.log('say')
   }
}

function flag(Constructor){
   Constructor.type = '哺乳类'
}
console.log(Animal.type)
function readonly(target,property,descriptor) {
   setTimeout(() => {
      console.log(target == Animal.prototype)
      console.log(descriptor)
   });
   
}

function before(target,property,descriptor) {
   console.log(descriptor)
}

在这里插入图片描述
可以写一些逻辑代码,例如切片

function before(target,property,descriptor) {
   console.log(descriptor)
   let oldSay = descriptor.value;
   descriptor.value = function () {
      console.log('before')
      oldSay.call(target)
   }
}

let animal = new Animal()
animal.say()

结果:
在这里插入图片描述


http://www.niftyadmin.cn/n/997515.html

相关文章

java中对象、成员变量、静态变量、方法的内存分配

2019独角兽企业重金招聘Python工程师标准>>> java中内存主要包含4块,即heap(堆内存)、stack(栈内存)、data segment(静态变量或是常量存放区)、codesegment(方法区). 堆内存中存放的是new出的对象,new出的对象只包含成员变量。 栈内存中&…

安卓逆向之hook框架---Frida Hook Java层修改函数返回值

本期用到 :pythonfrida模拟器 如果没布置Frida环境可以跳转此文: Hook神器: frida超详细安装教程 一、分析 APK:AliCrackme.apk 阿里安全比赛上的题目,目标无壳,一个简单的密码校验软件,只有输入正确的密码才能进入,…

MathType6.9按章节插入编号

先插入Chapter,然后修改break主要是该起始编号。 这样话会用一行红色红代码,选中,邮件字体,然后在格式里选择隐藏就好了,这个不能删除。

安卓逆向脱壳:Frida-DEXDump一吻杀一个人,三秒脱一个壳

本期用到 :pythonfrida模拟器Frida-DEXDump 如果没布置Frida环境可以跳转此文: Hook神器: frida超详细安装教程 一、前言 APP 加固发展到现在已经好几代了,从整体加固到代码抽取到虚拟机保护,加固和脱壳的方案也逐渐趋于稳定。随着保护越来越强&#xf…

linux bash $()和${}和$(())和(())

2019独角兽企业重金招聘Python工程师标准>>> $()和${}和$(())和(()) $()和${}的用法: 在 bash shell 中,$( ) 与 (反引号) 都是用来做命令替换用(command substitution)的。而 $( ) 并不见的每一种 shell 都能使用,若你用 bash2…

设置图片和文字的垂直居中

设置图片和文字的垂直居中。vertical-align:middle;图片竖向居中,然后文字就可以和图片对齐。 转载于:https://www.cnblogs.com/ganchuanpu/p/6221047.html

Linux + ProxyPool 搭建属于爬虫代理IP池

前言: 当爬虫达到一定速度时,大家都会遇到封Ip的情况,而搭建代理ip池是解决的最好方法,网络上有很多优秀的付费代理,但是作为白嫖党的我们又怎么能付钱那,本文将教会大家用一个成熟的开源项目搭建代理池。…

P1082 找朋友

描述 童年的我们,对各种事物充满了好奇与向往。这天,小朋友们对数字产生了兴趣,并且想和数字交朋友。可是,怎么分配这些数字才能使得每个小朋友都唯一地找到一个数字朋友呢?C小朋友说:咱们按自己…