ES 新特性与 TypeScript、JS 性能优化> 内容概要-直播

本文探讨JavaScript中的原型方法与直接在对象上定义方法的性能差异,展示了JSBench测试结果。同时,文章涉及Promise的微任务实现,解释了其在不同环境下的工作原理。此外,还讨论了TypeScript的模块化处理和Polyfill的使用,以及在Node.js环境中this的特殊行为。最后,提到了V8引擎的工作原理和内存管理,包括GC的新生代回收机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

20201109 直播

零、答疑

使用原型和不使用原型

  1. “对原型添加方法更好”,有疑惑,我在方法里面做一些访问属性的操作后,发现原型添加方法更消耗性能

    https://jsbench.me/

    function Person (id) {
     this.id = id
    }
    
    Person.prototype.say = function () {
     console.log(this.id, 'say~')
    }
    
    var p = new Person(Date.now())
    p.say()//p等于 Person里的this, 找不到say第一轮接续,接下来找第二轮沿着原型链
    
    // ===== vs =====
    
    function Person (id) {
     this.id = id
     this.say = function () {
       console.log(this.id, 'say~')
     }
    }
    
    var p = new Person(Date.now())
    p.say()//这里只找了一层就找到了
    
    function Person (id) {
     this.id = id
    }
    
    Person.prototype.say = function () {
     console.log(this.id, 'say~')
    }
    
    for (var i = 0; i < 1000; i++) {
     var p = new Person(Date.now())
     p.say()
    }
    
    // ===== vs =====
    
    function Person (id) {
     this.id = id
     this.say = function () {
       console.log(this.id, 'say~')
     }
    }
    
    for (var i = 0; i < 1000; i++) {
     var p = new Person(Date.now())
     p.say()
    }
    
总结
  • 挂原型更优是看情况的,如果这个对象重复使用才看得出优势,例如多次new,因为在内存指向的都是一个,不会存在重复创建的情况。
  • 如果写函数里面,每次new都会创建对应新的函数内存空间。

第二段代码开始明显就不一样了。

实现 Promise 微任务的问题

微任务不出调用栈,不会进消息队列(进微任务队列),promise前JS是没有微任务的(宏任务内的任务,子任务)

  1. 手写 Promise 源码中微任务实现的问题。

    由于老环境下微任务无法模拟,所以这不可能,Promise是原生代码,并不是代码去实现的

在这里插入图片描述是V8提供的内部成员。

TypeScript 的 Polyfill

  1. TypeScript 在实战中的一些代码片段,比如联合类型,可选值什么的,现在讲的太浅显了

  2. ts可以通过配置文件把代码编译至ES5,针对ES6新的API是否还得结合babel进行polyfill?

    TS 对于语言的编译,只是语法层面,如果是 API 层面的的补充,需要手动 Polyfill!

    1. 不使用第三方工具的情况下,需要手动引入 Polyfill
    2. 使用 Babel 自动化的 Polyfill
  3. 希望讲解Typescript是如何处理第三方库的,如何把我们自己的代码发布成npm包

    https://github.com/zce/caz
    在这里插入图片描述
    因为原作者不想维护TS的框架,微软创立了个组织,专门重构热门框架成TS的。
    在这里插入图片描述
    –save 代码阶段使用

  4. V8内部的工作原理

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y6Ls0nwV-1606135275848)(/Users/zce/Desktop/media/image-20201109192804679.png)]

  5. 想了解更多的Symbol类型的使用案例。
    创建独一无二的值

    • 私有属性(无法拿到symbol的值,打印也打印不出来for也是),序列化、遍历都拿不到
      私有属性获取办法
      在这里插入图片描述

    • Vuex / Redux 中的 Mutation / ActionType

  6. GC回收的新生代区回收机制,我看部分资料说从From到To的复制过程其实已经是整理过程了,然后并没有提到使用标记整理算法,想确认一下。

  7. 引用计数算法不会产生内存碎片吗?我看视频中没有提到这个。

引用计数算法没有明确空间回收后的整理操作,它是将单个垃圾空间整体回收,所以是没有碎片的。

  1. 模块化的疑难杂症,如webpack是如何将import,require进行转化的,require.default的本质原因,以及未来的模块化趋势

  2. 除js外,讲点css类的基本功,如现在的移动端开发的自适应,响应式问题,em,rem,vh等的适应场景和建议,如何设计最优雅的,如动效类

  3. 常用的界面样式库,组件库等,如何快速开发原型

    1. Bootstrap / Tailwindcss
      不想自己写样式可以直接拿现成的用
      在这里插入图片描述

  • 直接用 core-js:https://github.com/zloirock/core-js
  • 配合 babel 使用:https://babeljs.io/docs/en/babel-preset-typescript

Polyfill 垫片/补充(就是兼容处理)

if (!window.XMLHttpRequest) {
  window.XMLHttpRequest = function () { .... }
}

if (!Object.entries) {
  Object.entries = ...
}
// core-js 基本上把能 polyfill API 都实现了

// Object.defineProperty 完全无法 Polyfill
// Promise 微任务,用宏任务代替

// // import 'core-js/features/object'
import 'core-js/features/object'

// import 'core-js'

interface User {
  name: string
  age: number
  gender: 'male' | 'female'
}

const tony: User = {
  name: 'Tony Huang',
  age: 18,
  gender: 'male'
}

const entries = Object.entries(tony)

console.log(entries)

一、关于 this 的回顾

function foo () {
  console.log(this)
}

foo() // => 全局对象 / globalThis
foo.call(1) // => 1
const obj1 = {
  foo: function () {
    console.log(this)
  }
}

obj1.foo() // => obj1
const fn = obj1.foo
fn() // => window
const obj2 = {
  foo: function () {
    function bar () {
      console.log(this)
    }
    bar()
  }
}

obj2.foo()

关于 this 的总结:
this是执行上下文,调用决定

  1. 沿着作用域向上找最近的一个 function(不是箭头函数),看这个 function 最终是怎样执行的;

  2. this 的指向取决于所属 function 的调用方式,而不是定义;

  3. function 调用一般分为以下几种情况:

    1. 作为函数调用,即:foo()
      1. 指向全局对象(globalThis),注意严格模式问题,严格模式下是 undefined
    2. 作为方法调用,即:foo.bar() / foo.bar.baz() / foo['bar'] / foo[0]()
      1. 指向最终调用这个方法的对象
    3. 作为构造函数调用,即:new Foo()
      1. 指向一个新对象 Foo {}
    4. 特殊调用,即:foo.call() / foo.apply() / foo.bind()
      1. 参数指定成员
  4. 找不到所属的 function,就是全局对象

谢天谢地,以后再无 this 问题。。。

then:

var length = 10
function fn () {
  console.log(this.length)
}

const obj = {
  length: 5,
  method (fn) {
    // arguments[0] === fn // => true
    fn() //10
    arguments[0]()   
    // arguments.[0]() //[0]相当索引器,调用方法
  }
}

obj.method(fn, 1, 2)

谢天谢地,以后真的再无 this 问题。。。

Node.js 环境

  • 由于文件代码中最顶层的作用域实际上是一个伪全局环境,所以最顶层的 this 并不指向全局对象

严格模式

严格模式下原本应该指向全局的 this 都会指向 undefined


  • this
  • prototype
  • 声明提升
  • 闭包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值