20201109 直播
零、答疑
使用原型和不使用原型
-
“对原型添加方法更好”,有疑惑,我在方法里面做一些访问属性的操作后,发现原型添加方法更消耗性能
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是没有微任务的(宏任务内的任务,子任务)
-
手写 Promise 源码中微任务实现的问题。
由于老环境下微任务无法模拟,所以这不可能,Promise是原生代码,并不是代码去实现的
是V8提供的内部成员。
TypeScript 的 Polyfill
-
TypeScript 在实战中的一些代码片段,比如联合类型,可选值什么的,现在讲的太浅显了
-
ts可以通过配置文件把代码编译至ES5,针对ES6新的API是否还得结合babel进行polyfill?
TS 对于语言的编译,只是语法层面,如果是 API 层面的的补充,需要手动 Polyfill!
- 不使用第三方工具的情况下,需要手动引入 Polyfill
- 使用 Babel 自动化的 Polyfill
-
希望讲解Typescript是如何处理第三方库的,如何把我们自己的代码发布成npm包
https://github.com/zce/caz
因为原作者不想维护TS的框架,微软创立了个组织,专门重构热门框架成TS的。
–save 代码阶段使用 -
V8内部的工作原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y6Ls0nwV-1606135275848)
-
想了解更多的Symbol类型的使用案例。
创建独一无二的值-
私有属性(无法拿到symbol的值,打印也打印不出来for也是),序列化、遍历都拿不到
私有属性获取办法
-
Vuex / Redux 中的 Mutation / ActionType
-
-
GC回收的新生代区回收机制,我看部分资料说从From到To的复制过程其实已经是整理过程了,然后并没有提到使用标记整理算法,想确认一下。
-
引用计数算法不会产生内存碎片吗?我看视频中没有提到这个。
引用计数算法没有明确空间回收后的整理操作,它是将单个垃圾空间整体回收,所以是没有碎片的。
-
模块化的疑难杂症,如webpack是如何将import,require进行转化的,require.default的本质原因,以及未来的模块化趋势
-
除js外,讲点css类的基本功,如现在的移动端开发的自适应,响应式问题,em,rem,vh等的适应场景和建议,如何设计最优雅的,如动效类
-
常用的界面样式库,组件库等,如何快速开发原型
- Bootstrap / Tailwindcss
不想自己写样式可以直接拿现成的用
- 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是执行上下文,调用决定
-
沿着作用域向上找最近的一个 function(不是箭头函数),看这个 function 最终是怎样执行的;
-
this 的指向取决于所属 function 的调用方式,而不是定义;
-
function 调用一般分为以下几种情况:
- 作为函数调用,即:
foo()
- 指向全局对象(globalThis),注意严格模式问题,严格模式下是 undefined
- 作为方法调用,即:
foo.bar()
/foo.bar.baz()
/foo['bar']
/foo[0]()
- 指向最终调用这个方法的对象
- 作为构造函数调用,即:
new Foo()
- 指向一个新对象
Foo {}
- 指向一个新对象
- 特殊调用,即:
foo.call()
/foo.apply()
/foo.bind()
- 参数指定成员
- 作为函数调用,即:
-
找不到所属的 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
- 声明提升
- 闭包