很多人都说IT人员的黄金年龄在 35岁以下,过了保质期就会被淘汰,但是,事实真的是这样吗?我见过40岁以上的IT人员,他们并没有被这个行业所淘汰,相反,他们可以比年轻的IT人员拥有更高的工作效率,因为他们有更多的开发经验,他们有更深的知识储备,他们一直在充实自己,给自己充电。因为他们明白,不努力,不充实自己,不紧跟技术的发展,被淘汰是早晚的事情。
从事前端工作三年多,工作有忙也有闲,闲的时候也会学习给自己充电,但是,总是感觉学的多,忘得更多,总是感觉自己在抓不到重点的学,每天感觉都很迷茫,感觉自己对于好多的知识都很模糊,虽然知道的多,了解的多,但是好多东西其实只是学到了皮毛。参加【拉勾教育 大前端高薪训练营】已经两个多月了,每天听完课以后,都会记笔记,然后通过 博客,我感觉这种方式很好,在写博客的过程中,我会把每天学习的新的知识点再看一遍,这样的话,知识可以更加深刻的记录在脑海里。
在没有加入【拉勾教育 大前端高薪训练营】之前,我根本不知道什么叫函数式编程,什么是宏任务和微任务,什么是 虚拟 DOM, Vue 的底层代码是如何实现的,也不知道 call 的底层实现。现在,通过课程的学习,我知道该如何去使用他们,通过对 虚拟DOM 的学习,我知道该如何去分析其他框架。这些底层东西的学习,可以帮助我很好的学习 Vue、React 等。我现在刚刚学完Vue 的源码,了解了Vue 的底层实现机制,在使用Vue时,就会更加的得心应手。并且,除了一些特定的课程以外,在每次直播的时候,都会有加餐,加餐的内容可能是一些开发中的小技巧,也可能是一些最新的技术,还可能是一些重点难点的讲解,这些都可以让我更好的成长,收获更多。
在后期还会学习 React 源码、Vue 3.0 新特性、Node.js 、GraphQL 等课程,我相信当学完的时候,一定会与现在的我不一样,至少我的知识储备相较于现在,会得到更大程度的扩充。
下面,是我的一篇模拟 call 的底层实现的blog,欢迎朋友们查阅和指出不足之处。
JavaScript中,模拟 call 的底层实现
笔记来源:拉勾教育 大前端高薪训练营
面试题
function fn1 () {
console.log(1)
}
function fn2 () {
console.log(2)
}
// call 的作用
// 调用 call fn1函数,并改变fn1内部的this,将 this 指向 fn2
fn1.call(fn2) // 1
fn1.call.call(fn2) // 2
模拟 call 的实现
没有传参
// 让所有的函数对象,都具有 mycall 方法
// context.fn1()
Function.prototype.mycall = function mycall(context, ...args) {
// context = context || window
// ??
// 只有 context 的值是 null 或者 undefined 的时候,才会返回 window
context = context ?? window
// 此处的 this 指向的是 fn1 函数
// 临时把 this 存储进 context.fn 中
context.fn = this
const result = context.fn(...args)
delete context.fn
return result
}
执行过程
// fn1.mycall.mycall(fn2),执行过程
Function.prototype.mycall = function mycall(context, ...args) {
// context ---> fn2
context = context ?? window
// context.fn ---> this ---> mycall
// fn2.mycall
context.fn = this
// 暂停,等待执行 fn2.mycall (没有参数)
const result = context.fn(...args)
delete context.fn
return result
}
// 调用 fn2.mycalll (没传参数)
Function.prototype.mycall = function mycall(context, ...args) {
// context ---> Window
context = context ?? window
// context.fn ---> this ---> fn2
// window.fn2
context.fn = this
// window.fn2 (没有参数)
const result = context.fn(...args)
delete context.fn
return result
}
传入参数
// context.fn1()
Function.prototype.mycall = function mycall(context, ...args) {
// 此处要去处理 context 是原始值的问题
switch (typeof context) {
case 'number':
context = new Number(context)
break
case 'string':
context = new String(context)
break
case 'boolean':
context = new Boolean(context)
break
default:
// context = context || window
context = context ?? window
}
// 此处的 this 指向的是 fn1 函数
// 临时把 this 存储进 context.fn 中
context.fn = this
const result = context.fn(...args)
delete context.fn
return result
}
const obj = { name: 'zs' }
// fn1.mycall(obj)
fn1.mycall.mycall(fn2, "1", 2)
}
知乎地址