理论而非启发式:作为前端开发人员变得更好



使用基础知识而不是启发法成为更好的前端开发人员

我们的经验表明,非技术教育者和自学成才的人通常不依靠理论原理,而是依靠启发式方法。

启发式-开发人员从实践中学到的模式和经过验证的规则。 它们可以不完美地工作或以有限的方式工作,但是可以充分发挥作用,不需要认真考虑。 以下是一些启发式方法的示例:

  • “使用$(document).ready(function(){})在jQuery网站上初始化代码”
  • var self = this需要var self = this构造才能在回调函数中调用方法”
  • “箭头函数没有return

同时,理论原理可用于寻找其他问题的解决方案。 他总是忠诚,经常决定一个或另一个元素的具体用途。 理论原理包括,例如:


请注意:与严格的理论基础相比,我们仅列举了启发式示例,以强调启发式的手工性质。 没有一个启发式示例在所有情况下都是通用的,但是它们在很多情况下都可以工作,因此使用它们的开发人员在未完全了解其操作的情况下会收到工作代码。

理论方法的论点


我们经常碰到一个事实,即未经技术培训的开发人员不倾向于使用理论原理来解决问题。 通常,这可以通过以下事实来解释:在职业生涯的开始,他们没有机会学习它们,并且由于启发式方法令人满意地起作用,因此他们继续使用它们。

但是,尽管表面上很复杂,但是学习理论还是很有用的。 怎么了 然后,该理论将使您对解决方案的工作充满信心,并独立显示新问题的答案,而无需寻找其他人的解决方案。 在短期内,启发式算法似乎是一个简单而快速的解决方案,但它们往往会导致不完善的解决方案-甚至根本不完善。

此外,依靠启发式方法,您将永远不会学习如何真正解决问题。 您可能经常设法找到一个可行的解决方案,但是迟早您将陷入停顿,您将看不到任何出路。 C&P程序员在工作中依赖启发式。

开发人员技能水平标准


在采访前端开发人员时,我们为他们设置了编程任务,并说他们可以自由使用任何来源,无论是Google还是Stack Overflow。 这样,很容易确定开发者是否是启发式或理论的坚持者。

前者无一例外地使用Stack Overflow从或多或少合适的示例中复制代码。 只有当代码无法按计划工作时,他们才开始对它们进行微调。 他们经常失败。

后者倾向于在API文档中寻找答案。 在这里,他们可以找到有关特定函数需要使用多少参数或所需CSS属性的扩展形式的特定语法的信息。

在面试的前五分钟,您可以确切确定候选人属于哪种类型的程序员。

例子


以比尔为例。 他完成了几门培训课程,解决了许多JavaScript任务,并在业余时间编写了网站,但他并没有真正学习JavaScript。

一旦Bill遇到这样的对象:

 const usersById = { "5": { "id": "5", "name": "Adam", "registered": true }, "27": { "id": "27", "name": "Bobby", "registered": true }, "32": { "id": "32", "name": "Clarence", "registered": false }, "39": { "id": "39", "name": "Danielle", "registered": true }, "42": { "id": "42", "name": "Ekaterina", "registered": false } } 

这样的对象可以显示用户列表以及他们是否已注册特定事件。

假设Bill需要检索一个注册用户列表。 换句话说,将它们过滤掉。 他遇到了使用.filter()方法过滤列表的代码。 因此,他尝试了类似的方法:

 const attendees = usersById.filter(user => user.registered); 

这是他得到的:

 TypeError: usersById.filter is not a function 

Bill认为:“有些废话”,因为他看到了.filter()作为过滤器的代码。

问题在于,比尔依靠启发式方法。 他不了解filter是在数组上定义的方法,而usersById是不具有filter方法的常规对象。

困惑的Bill在Google上搜索“ javascript过滤器 ”。 他找到了许多对数组的引用,并意识到他需要将usersById转换为数组。 然后,通过询问“ javascript将对象转换为数组 ”,他使用Stack Overflow上的Object.keys()查找示例。 之后,他尝试:

 const attendees = Object.keys(usersById).filter(user => user.registered); 

这次没有显示该错误,但是令Bill惊讶的是, attendees字段仍然为空。

事实是Object.keys()返回对象的键,但不返回其值。 实际上, user变量名称很容易引起误解,因为它不是user对象,而是标识符(即字符串)。 由于未为字符串定义registered属性,因此filter将每个条目视为false,并且数组保留为空。

Bill仔细研究了堆栈溢出的答案,并进行了以下更改:

 const attendees = Object.keys(usersById).filter(id => usersById[id].registered); 

这次结果更好: ["5", "27", "39"] 。 但是,比尔想要获取访客对象,而不是其ID。

为了了解如何过滤访问者,恼怒的Bill搜索了一个“ javascript对象过滤器 ”,检查了Stack Overflow的搜索结果,并使用以下代码找到了答案

 Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} ); 

Bill复制这些行并尝试:

 const attendees = Object.filter(usersById, user => user.registered); 

一切正常-尽管尚不清楚原因。 比尔不明白为什么需要reduce量以及如何使用reduce 。 而且,Bill不了解他只是为全局Object定义了一种新的非标准方法。

但是Bill不在乎-可以! 后果对他还不感兴趣。

比尔做错了什么?


Bill尝试了一种启发式方法来解决该问题,并遇到以下问题:

  1. 在变量上使用.filter() ,Bill得到了TypeError 。 他不了解filter未在普通对象上定义。
  2. 他使用Object.keys() “将对象转换为数组”,但仅此一项并没有带来任何结果。 他需要创建一个对象值数组。
  3. 即使在接收到这些值并将它们用作过滤条件之后,他也仅接收到标识符,而不是与这些标识符关联的用户对象。 这是因为过滤后的数组包含一个ID,而不是用户对象。
  4. 随着时间的流逝,比尔放弃了这种方法,并在Internet上找到了可行的解决方案。 尽管如此,他仍然不了解它是如何工作的-并且不会浪费时间整理它,因为他还有其他事情要做。

这是一个人为的例子,但是我们遇到过许多以相同方式解决问题的开发人员。 为了有效地解决它们,您需要远离启发式方法并研究理论。

让我们继续基础


如果比尔是理论方法的拥护者,那么过程将如下所示:

  1. 从属性的意义上来说,要识别给定的输入数据并确定所需的输出: “我有一个对象,其键是代表ID的字符串,值是代表用户的对象。 我想要一个数组,其值将是用户对象-但仅是注册用户的对象”
  2. 要了解如何在对象内部进行搜索: “我知道可以通过调用Object.keys()获得对象中的键数组。 我想得到一个数组,因为数组支持枚举
  3. 要认识到此方法有助于获取键,您需要将键转换为值,并记住map-一种通过转换另一个数组的值来创建新数组的明显方法:

     Object.keys(usersById).map(id => usersById[id]) 
  4. 要查看您现在拥有一个可以过滤的用户对象数组,其中包含要过滤的实数值:

     Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered) 

这样去比尔,他可以为我们工作。

人们为什么不更经常诉诸理论?


有时他们只是不认识她。 大多数情况下,他们太忙了,无法找到时间学习解决问题的方式-他们只需要一切即可工作。 他们冒着将这种方法养成习惯的风险,这将成为他们技能发展的障碍。

为避免此类错误,请始终从理论入手。 在流程的每个阶段,请考虑要处理的数据类型。 不要一直依赖熟悉的模式,而要考虑原始数据类型:数组,对象,字符串等。 使用函数或方法时,请参考文档以确切了解哪些数据类型支持它们,它们采用哪些参数以及结果是什么。

使用这种方法,您可以在第一次尝试时找到可行的解决方案。 您可以确定其正确性,因为您是根据给定的输入和所需的输出特别选择了操作。 深入了解每个操作的基础知识(数据类型和返回值),而不要模糊业务表述(例如“注册用户”)。

Source: https://habr.com/ru/post/zh-CN458642/


All Articles