IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ES6中Class的方法不可遍历的原因,TS中遍历Class的方法出现二义性的问题 -> 正文阅读

[JavaScript知识库]ES6中Class的方法不可遍历的原因,TS中遍历Class的方法出现二义性的问题

前言

今天写了一段Ts代码,发现编译成ES5和ES6时的执行结果居然不同,花了点时间学习了一下,总结如下。

问题

在ts代码中,使用in操作符遍历对象成员,将代码编译成ES5和ES6时,结果是不同的。

原因

es6中class的所有非静态方法虽然是定义到原型对象上的,但是却是不可遍历的,源码如下

// 为target对象添加属性
function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i]
        // enumerable 默认为 false
        descriptor.enumerable = descriptor.enumerable || false
        descriptor.configurable = true
        if ('value' in descriptor) descriptor.writable = true
        Object.defineProperty(target, descriptor.key, descriptor)
    }
}

// 为 Constructor 添加原型属性或者静态属性
function _createClass(Constructor, protoProps, staticProps) {
    // 如果是原型属性,添加到原型对象上
    if (protoProps) _defineProperties(Constructor.prototype, protoProps)
    // 如果是静态属性,添加到构造函数上
    if (staticProps) _defineProperties(Constructor, staticProps)
    return Constructor
}

可以看到descriptor.enumerable = descriptor.enumerable || false这句代码设置了属性默认是不可遍历的,如果我们没有设置,属性默认不可遍历。

in操作符默认是可以遍历原型对象的成员的,但是下边代码不会有任何输出,因为原型对象的成员被设置了不可遍历。

class Person {
    say() {
        console.log("hello");
    }
}
let p = new Person();
for (const key in p) {
    console.log(key);
}

构造函数则没有这个问题,可以被遍历到。

function Person() {}
Person.prototype.say = function() {};
let p = new Person();
for (const key in p) {
    console.log(key); // say
}

这就导致了我遇到的问题,编译的ECMAScript版本不同,代码可能会有不同的运行结果。

class Person {
  say() {
    console.log("hello");
  }
}
let p = new Person();
for (const key in p) {
  console.log(key);
}

上边代码,如果使用默认设置编译为ES5时,会输出say,编译后的代码如下:
可以看到,其实是返回了一个构造函数,并设置了构造函数的原型。

var Person = /** @class */ (function () {
    function Person() {
    }
    Person.prototype.say = function () {
        console.log("hello");
    };
    return Person;
}());
var p = new Person();
for (var key in p) {
    console.log(key);
}

而如果设置编译为ES6,则不会有输出,编译后的代码如下(和编译前相同):

class Person {
  say() {
    console.log("hello");
  }
}
let p = new Person();
for (const key in p) {
  console.log(key);
}

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:02:05  更:2022-04-04 12:02:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:59:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码