首页 > 其他分享 >es6 class对象转换es5

es6 class对象转换es5

时间:2023-03-14 18:22:20浏览次数:58  
标签:function es6 es5 obj value descriptor key return class

在线转换工具 https://babeljs.io/repl

// es6 
class Person {
  static name = 'lisi'
  #age = null
  #sex = null
  constructor() {
    this.name = 'zhangsan'
  }
  set() {
    this.#age = 18
    this.#sex = 'nv'
  }
  get() {
    return this.name + '今年' + this.#age + '岁'
  }
  static say() {
    console.log(this.name + '说我今年' + this.#age + '成年了' + this.#run())
  }
  #run() {
    return '跑起来'
  }
}
// es5转换 
var _sex = /*#__PURE__*/ new WeakMap() // 私有属性映射
var _run = /*#__PURE__*/ new WeakSet() // 私有方法映射
// 创建一个自动执行的匿名函数
var Person = /*#__PURE__*/ (function () {
  // 创建构造函数
  function Person() {
    _classCallCheck(this, Person) // 检测类型是否能将类作为函数使用, 使用new关键字创建实例
    _classPrivateMethodInitSpec(this, _run) // 私有方法初始化
    _defineProperty(this, 'name', 'lisi') // 公共属性初始化赋值
    // 私有属性初始化赋值
    _classPrivateFieldInitSpec(this, _sex, {
      writable: true,
      value: null
    })
    this.name = 'zhangsan' // 执行class中constructor构造函数体其他语句
  }
  // 公共方法,静态方法初始化, 接收三个参数,实例,公共方法,静态方法
  _createClass(
    Person,
    [
      {
        key: 'set',
        value: function set() {
          this.name = 'wangwu' // 公共属性赋值
          this.age = 18 // 静态属性赋值
          _classPrivateFieldSet(this, _sex, 'nv') // 私有属性赋值
        }
      },
      {
        key: 'get',
        value: function get() {
          return this.name + '今年' + this.age + '岁'
        }
      }
    ],
    [
      {
        key: 'say',
        value: function say() {
          console.log(
            this.name + '说我今年' + this.age + '成年了' + _classPrivateMethodGet(this, _run, _run2).call(this)
          )
        }
      }
    ]
  )
  return Person
})()
function _run2() {
  // 私有方法
  return '可以跑起来了'
}
_defineProperty(Person, 'age', null) // 静态属性初始化赋值

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

// 类型检测
function _typeof(obj) {
  // const a = (表达式1, 表达式2, ...., 表达式n)
  // 从表达式1开始执行一直到n,最终返回n
  return (
    (_typeof =
      'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator
        ? function (obj) {
            return typeof obj
          }
        : function (obj) {
            return obj && 'function' == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype
              ? 'symbol'
              : typeof obj
          }),
    _typeof(obj) // typeof函数已被改变,并不会递归调用,调用的是前面重新赋值返回的函数
  )
}

// 属性注册
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key)
  if (key in obj) {
    // 判断是否在当前实例
    Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true })
  } else {
    obj[key] = value
  }
  return obj
}

// 对象key类型检测
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, 'string')
  return _typeof(key) === 'symbol' ? key : String(key)
}
function _toPrimitive(input, hint) {
  if (_typeof(input) !== 'object' || input === null) return input
  var prim = input[Symbol.toPrimitive]
  if (prim !== undefined) {
    var res = prim.call(input, hint || 'default')
    if (_typeof(res) !== 'object') return res
    throw new TypeError('@@toPrimitive must return a primitive value.')
  }
  return (hint === 'string' ? String : Number)(input)
}
// 私有属性注册
function _classPrivateFieldInitSpec(obj, privateMap, value) {
  _checkPrivateRedeclaration(obj, privateMap)
  privateMap.set(obj, value)
}
// 设置私有属性
function _classPrivateFieldSet(receiver, privateMap, value) {
  var descriptor = _classExtractFieldDescriptor(receiver, privateMap, 'set')
  _classApplyDescriptorSet(receiver, descriptor, value)
  return value
}
// 判断映射表中是否存在这个映射,存在即返回,否则抛错处理
function _classExtractFieldDescriptor(receiver, privateMap, action) {
  if (!privateMap.has(receiver)) {
    throw new TypeError('attempted to ' + action + ' private field on non-instance')
  }
  return privateMap.get(receiver)
}
// 将最新的值更新到映射表中
function _classApplyDescriptorSet(receiver, descriptor, value) {
  if (descriptor.set) {
    descriptor.set.call(receiver, value)
  } else {
    if (!descriptor.writable) {
      throw new TypeError('attempted to set read only private field')
    }
    descriptor.value = value
  }
}

// 方法注册
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps) // 公共方法注册
  if (staticProps) _defineProperties(Constructor, staticProps) // 静态方法注册
  Object.defineProperty(Constructor, 'prototype', { writable: false })
  return Constructor
}
// 对公共、静态方法遍历注册
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, _toPropertyKey(descriptor.key), descriptor)
  }
}
// 私有方法注册
function _classPrivateMethodInitSpec(obj, privateSet) {
  _checkPrivateRedeclaration(obj, privateSet)
  privateSet.add(obj)
}
// 是否存在私有方法,抛错处理
function _classPrivateMethodGet(receiver, privateSet, fn) {
  if (!privateSet.has(receiver)) {
    throw new TypeError('attempted to get private field on non-instance')
  }
  return fn
}

// 检测是否重复注册
function _checkPrivateRedeclaration(obj, privateCollection) {
  if (privateCollection.has(obj)) {
    throw new TypeError('Cannot initialize the same private elements twice on an object')
  }
}

标签:function,es6,es5,obj,value,descriptor,key,return,class
From: https://www.cnblogs.com/JunLan/p/17215881.html

相关文章

  • Swift 中的static 和 class 关键字使用及区别
    在Swift中,static和class关键字都可以用来修饰类的属性和方法,但它们之间有三个主要的区别:继承性:使用class修饰的属性和方法可以被子类重写,而使用static修饰的属......
  • SpringCloud多模块项目打包报错Unable to find main class
    SpringCloud多模块项目打包报错Unabletofindmainclass彻底解决方法:所有子模块都去掉打包插件代码,在parent模块的pom中加上 <build>    <plugins>   ......
  • 深入理解ES6--用模块封装代码
    用模块封装代码在模块顶部创建的变量不会自动被添加到全局共享作用域(模块顶部this的值为undefined),必须导出后,外部代码才可访问。浏览器中使用模块​​<script>​​的type属......
  • 深入理解ES6--迭代器、生成器、代理、反射、Promise
    迭代器(Iterator)和生成器(Generator)for-of循环及展开运算符…都是针对迭代器的!!!不能使用箭头函数来创建生成器;ES6函数的简写方式可以(只需在函数名前加星号)可迭代对象具有Symbol......
  • 深入理解ES6--Set、Map及Symbol
    Set集合和Map集合Set集合是一种无重复元素的列表,通常用来检测给定的值在某个集合中是否存在;Map集合内含多组键值对,通常用来缓存频繁取用的数据。ES5中的问题varmap=Objec......
  • vscode中配置c#程序中的Configuration,使其输出在console.exe类型与classlib库类型之间
    应用场景:最终目标是输出classlib库类型为dll,给js程序调用;但是中途需要可以断点调试。最初做法是另外创建个console程序,引用目标类库,但是在vscode中不知道怎么断点调试引用......
  • CDS即Class-Data Sharing
    引用:https://docs.oracle.com/en/java/javase/17/vm/class-data-sharing.html#GUID-7EAA3411-8CF0-4D19-BD05-DF5E1780AA91 类数据共享(CDS)功能,该功能有助于......
  • class
    class1.类初始化时,代码块优先本类构造器执行2.静态代码块优先于普通代码块执行3.等级相同的代码(代码块/变量),按照定义的先后顺序执行4.构造器先执行父类构造器,后执行子......
  • ES6的模块化
    一、模块化的概念:在进行项目分析或者编码时,先把项目进行拆分,拆分成很多的类,对象,很多的函数等等。能够提高代码的复用性。这些被拆分出来的类型,对象,函数就是模块。就像......
  • Day02-ES6新语法
    ES6新语法糖(初级)1什么是ES6JS语法分三块ECMAScript:基础语法BOM浏览器对象historylocationwindowDOM文档对象document编程语言JavaScript是ECMAScr......