回答了12个常见的JavaScript问题

IT资讯 2018-07-06 94 次浏览 0 条评论

这些问题甚至让经验丰富的开发人员感到难过。

JavaScript是最灵活的网页设计工具之一,正如我们的JavaScript文章展示的顶级示例。但即使使用最大的工具,也总是需要学习和发现。

以下是关于JavaScript的12个问题(和答案),这些问题让许多开发人员感到困惑 - 甚至是经验丰富的JavaScript编码员。

在这个页面上,我们会遇到常见问题和答案,包括那些经常在求职面试中小跑的问题和答案。在下一页中,我们将更深入地了解两个更复杂的领域:如何使用JavaScript来提高网站性能,以及如何使用面向未来的JavaScript代码。

19个精彩的JQuery插件
01.什么是原型继承,它有多大用处?
在JavaScript中,几乎所有东西都是对象。每个对象都有一个原型,从中继承了值和行为。如果一个对象不包含被请求的属性,JS将在其原型中查找它。它继续进行原型链直到找到匹配,或返回错误。

在创建共享相同值和操作的对象时,这非常有用。通过将这些存在于原型上,只需要存在一个副本,从而使项目内存高效。

var parent = {inherit: true}
var childA = Object.create(parent);
var childB = {};
Object.setPrototypeOf(childB, parent);
class childC extends parent {}

可以使用Object.create()或在使用Object.setPrototypeOf()之后将原型添加到创建对象。ES2015有一个'class'关键字,当与'extends'一起使用时,将使用该值作为其原型。

02.如何使用JavaScript来改善网络上的可访问性?
现代Web辅助功能工具通常能够处理JavaScript和动态内容。它可用于帮助这些技术,只要它被用作增强而不是功能所需。

协助用户的常用方法是提供有用的焦点管理。例如,日历应该能够使用箭头键循环几天,上下键一次跳过一周。这只是在焦点位于该组件内时监听键盘事件的情况。

还应该为屏幕阅读器宣布由于JavaScript而发生的重要数据更改,例如表单反馈。通常,这是通过将容器标记为活动区域来实现的。

03.什么是事件冒泡?它与事件捕获有何不同?

Javascript事件冒泡图形

事件委托是一种使用事件冒泡功能的技术。通过向父元素添加侦听器,开发人员会收到有关其任何子节点的事件的警报
事件捕获和冒泡都是称为“事件传播”的过程的一部分,其中浏览器响应页面上发生的事件。较旧的浏览器曾经做过一个或另一个,但现在他们都做了两个。

第一阶段 - 捕获阶段 - 在事件发生时立即发生。它从最顶层开始,根据事件,可以是“文档”或“窗口”。从那里它通过<html>和其中的任何生命,直到它到达事件发生在其中的元素。

第二阶段 - 冒泡阶段 - 然后发生。它重复了这个过程,但相反,从事件触发的元素开始,并“冒泡”到最顶层的<html>元素。添加事件侦听器时,这是默认值。

04.事件委派如何改进具有大量交互元素的网站上的代码?
网站通常会在页面上定期更改大量动态内容。如果这些元素需要是交互式的,那么这些元素需要某种事件监听器来获取这些交互。如果每个元素都需要自己的监听器,这会使代码混乱并增加浏览器需要跟踪的内容。

事件委托是一种使用事件冒泡功能的技术。通过向父元素添加侦听器,开发人员会收到有关其任何子节点的事件的警报。

parentEl.addEventListener('click', function(e) {
if(e.target && e.target.nodeName == 'BUTTON') {
// Button clicked
} });

在事件回调中,该事件的原始目标将始终是“目标”,可用于决定下一步做什么。例如,data属性可以包含ID以引用对象属性。

05.什么是闭包,它们如何在组织代码时有用?
JavaScript中的函数使用所谓的“词法环境”,这意味着它可以访问外部定义的变量,但内部定义的变量只能在其中访问。

function outer() {
let x = 'Web Designer';
function shout() {
alert(`I love ${x}!`);
}
shout(); }

调用outer()将显示“我喜欢Web Designer!”,但是如果在外部()之外引用“shout”或“x” ,则两者都将是未定义的。闭包是一种功能与其词汇环境的结合。在这种情况下,闭包是“外部”功能。

这些在创建多个组件时很有用,因为内部声明的任何内容都不会影响其他组件 它们可以用于创建私有函数和变量,其方式与其他面向对象语言(如Python)类似。模块模式广泛使用闭包来为模块提供结构化的交互方式。

06.在一段代码的顶部,“使用严格”是什么意思?
ES5引入了一个名为“严格模式”的可选JavaScript变体。在严格模式下,早期版本的怪癖会抛出错误而不是导致意外行为。

function strictFunction() {
'use strict';
myVar = 4; //ReferenceError }

上面我们正在访问一个不存在的变量。在严格模式之外,这会将myVar添加到全局范围,如果我们不小心,可以完全覆盖脚本中先前定义的功能。在严格模式下,这会抛出错误并停止任何破坏。默认情况下,ES2015模块处于严格模式,但在使用函数创建的闭包中,“use strict”可以应用于函数级别以及整个文件。

07.“吊装”一词对于JavaScript的含义是什么意思?
JavaScript的独特之处在于它在分发之前不需要编译。浏览器会在找到脚本时编译脚本,并记录在其中声明的任何函数和变量。

然后浏览器进行第二次传递以执行代码,知道这些函数和变量的适用位置。当执行一个块时,它的函数和变量声明被“提升”到块的顶部。

welcome("Matt"); //"Welcome, Matt."
function welcome(name) {
return `Welcome, ${name}.`;
}

在这个例子中,我们可以使用'welcome'函数,因为它被提升到脚本的顶部。

08.箭头功能和常规功能有什么区别?
ES2015提供了许多更改,其中一个是快速影响箭头功能。

function CountUp() {
this.x = 0;
setInterval(() => console.log(++this.x), 1000); }
var a = new CountUp();

尽管写入时间较短,但关键的区别在于箭头函数不会为“this”创建自己的值。他们将改为使用封闭块的值。在上面的例子中,这将每秒注销1,2,3等。使用常规函数,this.x将是未定义的,因此它将记录NaN。箭头函数的主体被假定为它的返回值。这使得它们对于传递值的promises非常有用。常规函数必须显式返回值,否则将返回undefined。

09.我应该在哪里使用'let'和'const'关键字而不是'var'?
ES2015的另一个根本变化是引入了'let'和'const'作为定义变量的替代方法。以这种方式声明的变量仅限于它们所定义的块。这样可以更加确定在不同块内创建的值不会干扰外部代码。

for(let x=1; x<=3; x++) {
console.log(x); // 1, 2, 3}
console.log(x); // "x is not defined"

如果变量的值不会改变,请使用'const'而不是'let'。尝试重新定义常量时会引发错误。对象和数组变量仍然可以在内部更改,但不会完全替换。

'let'和'const'都不像'var'那样被提升,因此在初始化之前不能被引用。在块的开始和初始化之间被称为“时间死区”并且通常可能是混淆的来源。

10.什么是函数式编程?它有何不同?

功能编程图形

功能编程提供了不同的思维方式

它是通过仅通过函数传递应用程序状态来创建程序的另一种方法。通过避免副作用,可以开发易于理解的代码。

传统上,JavaScript项目是使用面向对象的结构构建的。有关程序当前状态的信息保存在对象中,随着页面的更改而更新。

功能编程提供了不同的思维方式。虽然像F#这样的语言已经使用了一段时间,但ES2015为JavaScript带来了重要的方法,可以将其打开到网络上。

所有工作都必须在'纯'功能内完成。这些函数不受该函数范围之外的任何数据的影响。换句话说,如果向函数提供相同的值,则将始终返回相同的结果。

这也意味着函数之间不存在共享状态。应用程序中需要使用的任何状态都应作为参数传递给函数,而不是直接从函数中访问。

最后,代码应避免在制作后更改值。例如,对象的每次更改都应返回该对象的副本,并更改​​值。这是为了避免副作用,这可能会导致错误并使代码更难以测试。

 

11.如何使用JS来提高网站的性能?
在大多数网页浏览是在手机或平板电脑上进行的时候,性能至关重要。并非每个人都拥有最新的设备,每次延迟和口吃都会让客户付出代价。值得庆幸的是,有很多方法可以使用JavaScript来阻止这种情况发生。

保持被动

锯齿状滚动是一个明显的迹象。在某些情况下,由于应用于页面的侦听器,浏览器被迫等待。诸如'wheel'或'touchmove'之类的事件能够取消滚动,因此页面必须等到事件完成才能开始默认滚动行为。

这可能导致不稳定和不一致的滚动,这会导致糟糕的用户体验。

document.addEventListener('touchmove', handler, {passive: true});

要解决此问题,请在添加事件侦听器时将对象作为第三个参数传递。通过将事件标记为被动,浏览器可以假设滚动不会受到影响,因此可以立即启动。

第三个参数替换旧浏览器中的“useCapture”选项,因此在使用此类侦听器时使用特征检测非常重要。要有意禁用滚动,在CSS中应用'touch-action:none'将有助于更多浏览器。

节流事件

滚动和调整大小等事件尽可能快地确保听到的内容可以保持最新。如果在每个事件上发生资源密集的事情,这可能会使页面快速停止。

const resizeDebounce = debounce(() => {
// Code for resize event }, 200);
window.addEventListener('resize', resizeDebounce);

Debouncing是一种技术,可以限制调用其中一个事件的回调频率。debounce函数的实现以及调用函数的频率因项目而异,但例如将事件减少到每秒五次,将会在页面上立即得到改进。

专注于视口

滚动事件的常见用途是检测元素何时进入页面的视图。即使进行去抖动,调用getBoundingClientRect()也需要浏览器重新分析整个页面的布局。有一个名为IntersectionObserver的新浏览器API,它通过在进入或退出视口时调用函数来报告观察元素的可见性。对于无限滚动网站,这可以用作删除或回收旧视图的标志。

IntersectionObserver适用于除Safari之外的所有最新浏览器。值得使用这个API并回归旧技术,因为差异非常明显。

分开昂贵的工作

使用大型数据集或处理大型文件(如图像)时,JavaScript可以快速锁定浏览器窗口。所有工作都在单个线程上执行,因此如果该线程繁忙,则接口无法更新。

如果您知道某个进程需要很长时间才能运行,那么将它放在Web工作者中是个好主意。这些是在单独的线程上运行的脚本,使用户界面顺利运行。脚本可以通过特殊的消息方法相互通信。Web worker无法访问窗口对象上的DOM和某些属性,因此可以使用这些消息传递必要的信息。

12.我如何面向未来的JavaScript代码?
JavaScript的核心原则之一是它总是试图避免在可能的情况下破坏更改。今天编写的绝大多数代码仍将在十年后运行,即使在这个不断变化的行业中也是如此。

然而,仅仅因为代码块运行并不意味着它是面向未来的。几年后你的代码库仍然有意义吗?

避免意大利面条代码

首次创建项目时,将所有内容编写在一起可能很诱人。虽然这使得它明确了每个代码块正在做什么,但它也意味着所有行为也耦合在一起。如果项目的另一个区域需要该功能,它将被复制或重写。如果发现错误或添加了新功能,则每个版本都需要单独更新,这可能是一个耗时的过程。

通过保持代码模块化,可以在需要的地方包含功能。一旦编写完成,任何更改都可立即获得。可以在不影响项目其余部分的情况下实现诸如模块模式之类的技术,这使得它们更容易实现。

框架无关

许多现代框架,如React或Polymer,都鼓励开发人员通过创建组件来保持模块化。每个人都有自己的方式在项目的其他部分之间进行沟通。

当下一个最佳框架到来时会发生什么?切换 - 甚至只是更新 - 框架可能是一项艰巨的任务。找到这些旧组件协同工作的新方法可能会耗费宝贵的时间。

尽可能使用本机JavaScript功能来实现结果。这样,当改变框架时,这些摩擦点被最小化。例如,在将对象传递给组件之前使用对象来处理数据操作。

这在编写通用JavaScript时也很有用。通过避免在可能的情况下使用基于浏览器的API,可以在Node内部的浏览器和服务器上重用代码。

清理

编写模块后,保持清洁。阅读它们的任何人都应该了解它的功能以加快调试速度。

let activeUsers = users.filter(user => user.active === true);
自我记录代码是一种强大的工具,可以为您的代码提供面向未来的证明。例如,对迭代器中的变量使用描述性名称可以比“i”这样的通用名称更清晰。

最重要的是,要保持一致。通过坚持统一的风格,所有代码都变得可读。使用样式指南来定义代码的外观,并使用ESLint等工具来强制执行它。

大规模工作

可读性也延伸到项目结构。如果没有一个,事情就会很快变得无法抗拒。

首次启动时,将文件放在一个目录中可以保持简单。当脚本导入模块时,不会混淆它们的位置。

随着项目的老化,大量文件可能会在大众中丢失。保持一个可以很好地扩展的结构,例如在“用户”目录中存储处理用户的所有模块。最终,最佳结构将取决于项目。对于单页面应用程序,必须保持模型,视图和控制器逻辑分离。

让事情变得可测试

与Jest网站的桌上的笔记本电脑打开

使用Jest等工具定期运行测试,以确保一切正常
像React这样的框架鼓励创建小型,可重用的组件。即使具有可扩展的项目结构,也很难确保它们仍能正常工作。通过编写测试,可以放心地部署项目。

单元测试将在模块级别工作。像Mocha和Jest这样的工具允许开发人员为给定的输入定义预期输出。定期运行这些测试可以确保没有副作用。

模块需要以一种可以单独测试的方式编写。这意味着拥有尽可能少的外部依赖关系而不依赖于全局状态。

项目测试还有很多,例如集成和功能测试。这些应该涵盖尽可能多的项目,以保持代码在未来很长时间内工作。

明天的语言

Babel网站的截图

通过使用像Babel这样的转换器确保您的代码在旧版浏览器中运行
然而,面向未来的代码的最佳方法是将其编写为未来的语法。虽然这听起来像是迈向未知的一步,但有些工具可以让它变得尽可能简单。

Babel是一个转换器,它是一种将一种形式的JavaScript转换为另一种形式的工具。这用于将现代代码转换为旧浏览器和环境可以理解的格式。

ES2015带来了很多JavaScript,可以帮助编写干净的代码,例如箭头函数,promises和本机模块。最新标准 - ES2017 - 通过异步功能带来更多便利鉴于正确的预设,Babel可以帮助将所有这些转换为现在使用的代码。

最终,项目将能够完全跳过转换步骤。但就目前而言,它们是保持代码面向未来的必要条件。

0

【飞龙网.COM】不一样的IT资讯网,艺术,设计,插画,资源技巧分享!

发表评论