你应该知道的6个高级JavaScript概念

WebFX总统。Bill在互联网营销行业有超过25年的经验,擅长SEO、UX、信息架构、营销自动化等。William在Shippensburg和MIT的科学计算和教育背景为MarketingCloudFX和WebFX的其他关键研发项目提供了基础。

你应该知道的6个高级JavaScript技术在过去的几年里,有很多文章都在讨论JavaScript的最佳实践技术。我想我将稍微超出这些文章的范围,概述一些我个人使用过或读过的高级JavaScript概念和技术,在某些情况下可能是无价的。本文不一定涵盖我所描述的方法的所有细节,但提供了一个概述,以及带代码的高级JavaScript示例。

1.闭包扩展变量作用域

JavaScript中的闭包是一个相当直接的概念,已经在许多深入的在线文章中讨论过。它们简单的事实并不一定意味着它们简单,正如涵盖该主题的大量文章所看到的那样。简单地说,闭包允许将变量作用域扩展到函数的普通作用域限制之外。

我喜欢Jeremy Keith在书中描述闭包的方式防弹Ajax:

“闭包可以看作是一种区域性的范围:比本地更广,但没有全球那么广。”

要创建闭包,你需要在一个函数中嵌套一个函数。这个内部函数可以访问父函数作用域中的所有变量。在面向对象脚本中创建方法和属性时,这很方便。

下面是一个简单的例子,演示了闭包的用法:

函数myObject() {this。property1 =“value1”;这一点。property2 = value2”;var newValue = this.property1;这一点。performMethod = function() {myMethodValue = newValue;返回myMethodValue;};} var myObjectInstance = new myObject();警报(myObjectInstance.performMethod ());

脚本的关键部分是嵌套的匿名函数(用绿色突出显示)和方法调用警报函数(最后一行)。因为警报中的方法实际上是在调用一个嵌套函数,该方法能够读取被调用变量的值newValue,即使认为变量不在匿名函数的范围内,还是方法。开发人员一直在使用闭包,可能是在不知情的情况下,因为每当匿名函数嵌套在另一个函数中并利用父函数作用域中的变量时,就会创建闭包。

当调用该方法(内部函数)时,闭包的威力就显露出来了,通常不能访问的值在“区域”作用域内,因此可以作为任何其他值使用。关于闭包及其与作用域的关系,请参阅下面的参考资料。我也强烈建议你去找一本好的高级JavaScript书,它提供了与闭包相关的概念的很好的讨论。

进一步的阅读

  • 解释JavaScript作用域和闭包(Robert Nyman)
  • JavaScript中的闭包(James Padolsey)
  • Jibbering.com上的JavasCript闭包
  • 傻瓜的JavaScript闭包

2.传递可选参数的对象字面量

在处理可以接受大量可选参数的函数时,这里有一个方便的编码技巧,请记住。与传统方式传递大量参数不同,你可以只传递一个参数,它最终是在对象字面量中声明的参数集合,而不是以传统方式传递大量参数,这会不必要地使函数变得复杂。首先,让我们看看如何以典型的方式来完成这一操作,这样我们就可以看到对比:

函数showStatistics(名字,球队,位置,平均,全垒打,rbi){文档。写(“< p > < >强名称:< / >强”+参数[0]+ < br / >);文档。写(“< >强团队:< / >强”+参数[1]+ < br / >);If (typeof arguments[2] === "string"){文档。写(“< >强位置:< / >强”+位置+ < br / >);} if (typeof arguments[3] === "number"){文档。write("Batting Average: " + Average + "
");} if (typeof实参[4]=== "number"){文档。write("Home Runs: " + homeruns + "
");} if (typeof实参[5]=== "number"){文档。write("Runs Batted In: " + rbi + "

"); } } showStatistics("Mark Teixeira"); showStatistics("Mark Teixeira", "New York Yankees"); showStatistics("Mark Teixeira", "New York Yankees", "1st Base", .284, 32, 101);

上面的函数最多可以接受6个参数。

前两个参数是强制性的,所以在函数内部,我们不会检查它们是否存在。后4个参数不是强制性的,所以我们只在它们存在的情况下显示它们的值。我们调用该函数3次不同的次数(最后3行),每次都有不同数量的参数。

你可以看到,如果传递的参数的数量是几十个,或更多,代码可能看起来有点乱,并将更难维护,或读取。现在让我们看看同样的代码,使用对象字面量来传递参数:

函数showStatistics (args){文档。写(“< p > < >强名称:< / >强”+ args.name + < br / >);文档。write("团队: " +参数。Team + "
");如果(typeof arg游戏。位置=== "string") { document.write("Position: " + args.position + "
"); } if (typeof args.average === "number") { document.write("Average: " + args.average + "
"); } if (typeof args.homeruns === "number") { document.write("Home Runs: " + args.homeruns + "
"); } if (typeof args.rbi === "number") { document.write("Runs Batted In: " + args.rbi + "

"); } }showStatistics({名字:“马克·特谢拉”});showStatistics({姓名:“马克·特谢拉”,球队:“纽约扬基队”});showStatistics({姓名:“马克·特谢拉”,队伍:“纽约扬基队”,位置:“一垒”,场均:.284,本垒打:32,rbi: 101});

从技术上讲,第二种传递参数的方法可能需要更多一点的代码,但有了大量的参数集合,有几个优点。首先,函数本身简化了,因为它只接受一个参数(arg游戏),它是一个集合,集合了从对象字面量(的名字,团队,位置等等)。

另外,实际的参数值很容易阅读,也很容易理解、更新或修改,因为值和参数引用之间的相关性更直接。如果函数只需要少量的实参,那么这个方法就没有必要了,实际上可能会产生相反的效果。所以,要慎用这种方法,而且只有在预见到参数集合随着时间的推移难以维护的情况下才可以使用。

进一步的阅读

3.DOM元素的上下文定位

有时你需要遍历DOM并获得对特定元素或元素组的访问权,但由于某些限制,你可能无法通过HTML代码中的CSS类名或ID直接访问元素。这可能是因为通过富文本编辑器生成的用户生成内容,或从数据库中提取的动态内容。无论如何,通过JavaScript访问那些未识别的DOM元素并不是不可能的。

使用我所说的“上下文定位”,你可以访问和修改DOM中的几乎任何元素。只要你有一个包含你想要目标的元素的通用模板的映射,你就可以访问那个元素并像处理一个有类名或ID的元素一样操作它。让我们来创建一些基本的HTML代码,作为我们的示例页面:

< div id = "头" > < h1 >网站标题< / h1 > < / div > < div id =“侧边栏”> < ul > <李> < a href = " # " >测试< / > < /李> <李> < a href = " # " >测试< / > < /李> <李> < a href = " # " >测试< / > < /李> <李> < a href = " # " >测试< / > < /李> <李> < a href = " # " >测试< / > < /李> <李> < a href = " # " >测试< / > < /李> < / ul > < / div > < div id =“内容”> < h2 >页面标题< / h2 > < p > < a href = " # " > Lorum添加链接< / >。

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas。前庭tortorquam, feugiat vitae, ulicies eget, tempor sit amet, ante。我的前庭是自由的,永远都是自由的。

Aenean ultricies mi vitae est. Mauris placerat eleifend leo。Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas。

前庭tortorquam, feugiat vitae, ulicies eget, tempor sit amet, ante。我的前庭是自由的,永远都是自由的。Aenean ultricies mi vitae est。

Mauris placerat eleifend leo。

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Aenean ultricies mi vitae est. Mauris placerat eleifend leo。Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas。

前庭tortorquam, feugiat vitae, ulicies eget, tempor sit amet, ante。我的前庭是自由的,永远都是自由的。Aenean ultricies mi vitae est。

Mauris placerat eleifend leo。< / p > < / div > < div id =“页脚”> < p >版权| < a href = " # " >与< / > | < a href = " # " > < / >政策|隐私< a href = " # " > < / > < / p > < / div >

使用上面的HTML代码,如果我们想要瞄准页面上所有的锚标记,我们可以收集它们,像这样操作它们:

var myLinkCollection = document。getElementsByTagName(“”);for (i=0;i
         

然而,如果我们只想瞄准页脚中的锚标签,我们会基于它们的上下文,或周围的元素来瞄准它们,像这样:

var myFooterElement = document.getElementById(“页脚”);var myLinksInFooter = myFooterElement.getElementsByTagName(“”);for (i=0;i
         

第一行获取了对页脚元素的引用。第二行收集所有元素<一>页脚内的标签。

然后我们循环遍历它们,对它们做我们想做的事情。因此,即使它们没有通过类名分组,它们也是可访问的。你可以通过使用节点属性来完成同样的事情,如下所示。

var myLinkCollection = document。

getElementsByTagName(“”);for (i=0;imyLinkCollection[我].parentNode.parentNode.id=== "footer"){//在这里用页脚锚标记做点什么}}

类似的代码可以用来针对“内容”部分内的单个锚标记。我们还可以限制我们的锚标记搜索,只包括具有href属性集,以避免找到任何页内链接。的方法来做到这一点getAttribute方法:

var myLinkCollection = document.getElementsByTagName("a");for (i=0;i

getAttribute(“href”)){//在这里对锚标签做一些事情}}

最后,你会注意到有一个< span >标签内联样式。内联样式可能是通过内容管理系统生成的,所以你可能没有能力直接编辑它。你可以针对所有< span >像这样具有内联样式的元素:

var myLinkCollection = document。

getElementsByTagName(“跨度”);for (i=0;i

上下文定位的可能性是无穷无尽的,如果你正在使用一个JavaScript库,规范化浏览器差异并简化DOM操作,那么还有更多的选项可用。

进一步阅读:

4.使用名称空间防止冲突

如果您正在进行大量的原始JavaScript编码,并且怀疑可以对您正在处理的相同页面进行添加,那么您可以通过为您的代码提供自己的名称空间来防止将来与您的代码发生任何冲突。面向对象的JavaScript实现了类似于名称空间的原则,因为属性和方法是在对象内部声明的,因此不太可能发生冲突。然而,通过对象名称可能会产生冲突。

而且很有可能,冲突会“悄无声息”地发生,因此你可能不会立即被提醒到这个问题。您可以通过创建一个惟一的名称空间来防止所有冲突。让我们使用showStatistics函数演示如何将代码封装到自己的命名空间中:

if (typeof MY == "undefined") {MY = new Object();我的。CUSTOM = new Object();} MY.CUSTOM.namespace =函数(){函数showStatistics(args){文档。写(“< p > < >强名称:< / >强”+ args.name + < br / >);文档。write("团队: " +参数。Team + "
");如果(typeof arg游戏。位置=== "string") { document.write("Position: " + args.position + "
"); } if (typeof args.average === "number") { document.write("Average: " + args.average + "
"); } if (typeof args.homeruns === "number") { document.write("Home Runs: " + args.homeruns + "
"); } if (typeof args.rbi === "number") { document.write("Runs Batted In: " + args.rbi + "

"); } } showStatistics({ name: "Mark Teixeira", team: "New York Yankees", position: "1st Base", average: .284, homeruns: 32, rbi: 101 }); } MY.CUSTOM.namespace();

前几行通过检查“我的对象已经存在。

这个对象可以是你想要的任何东西。只要选一个你认为永远不会再用的名字就可以了。后我的对象创建后,我们就可以创建自定义对象的属性我的对象。

那么我们的名称空间函数成为方法的我的。自定义对象。请记住“我的”、“自定义”和“名称空间,都可以是您自己的自定义名称。我选择这些是为了演示。

他们可能会CHEESEBURGER.ONIONS.pickles如果你想要!的showStatistics函数与前面使用对象字面量传入值的例子完全相同。但在本例中,整个函数,包括对象字面量,都封装在里面my.custom.namespace

最后一行使用点表示法调用整个函数,函数的运行与正常情况完全相同,除了它被保护不与另一个名为“showStatistics”。

进一步阅读:

5.混合应用程序开发

如果结合使用JavaScript库和原始JavaScript代码,就可以创建功能强大的JavaScript应用程序。许多JavaScript库用于实现“漂亮的”动画和其他可定制的效果——有时通过插件——这些效果通常不需要添加太多东西,只需要添加一些自定义值。另一方面,可能在某些情况下,你想要完成客户端特定的要求。

可能是库中没有的东西,需要大量的编码,可能会利用Ajax和各种DOM方法。重新发明轮子没有任何意义。你可以实现你最喜欢的JavaScript库,并利用其简化的Ajax调用、DOM方法和浏览器差异的规范化。

因此,在创建特定于项目的定制脚本的同时,您可以利用库的优势。

进一步阅读:

6.HTML渲染可读

最后,这是一种在需要通过JavaScript动态生成几十行HTML代码的情况下使用的技术。举个下面的例子:

var pageContainer = document.getElementById(“容器”);var pageTitle = "内容标题";var authorBio =“Lorum先生Ipsum”;var pageContent =“Lorum ipsum line text here.”

Lorum ipsum行文字在这里。Lorum ipsum行文字在这里。Lorum ipsum line text在这里。

Lorum ipsum行文字在这里。Lorum ipsum行文字在这里。Lorum ipsum line text在这里。

Lorum ipsum行文字在这里。Lorum ipsum line text here.”;var footerContent = "版权所有2009";var HTMLCode = ' < h1 > ' + pageTitle +”< / h1 > < div id =“内容”> < p > ' + pageContent +”< / p > < div id = " author_bio " > < p > ' + authorBio +”< / p > < / div > < / div > < div id =“页脚”> < p > ' + footerContent +”< / p > < / div >”;pageContainer。innerHTML = HTMLCode;

上面要注意的行声明了HTMLCode变量的值。它只在生成的源代码中显示,因为它利用了“新行”字符,所以它看起来像完美的HTML。

但如果这行代码再长一点,在.js文件中读取和维护就会非常困难。下面是与上面相同的代码,但是实现了一种更有条理的显示HTML的方法:

var pageContainer = document.getElementById(“容器”);var pageTitle = "内容标题";var authorBio =“Lorum先生Ipsum”;var pageContent =“Lorum ipsum line text here.”

Lorum ipsum行文字在这里。Lorum ipsum行文字在这里。Lorum ipsum line text在这里。

Lorum ipsum行文字在这里。Lorum ipsum行文字在这里。Lorum ipsum line text在这里。

Lorum ipsum行文字在这里。Lorum ipsum line text here.”;var HTMLCode = ' ' + '< h1 >“+ pageTitle +”< / h1 >的< div id =“内容”>“+”< p >“+ pageContent +”< / p > ' + ' < div id =“author_bio”>“+”< p >“+ authorBio +”< / p >“+”< / div > " < / div > ' + ' < div id =“页脚”>“+”< p >“+ footerContent +”< / p >”+“< / div >”;pageContainer。innerHTML = HTMLCode;

现在的代码可读性强多了,并且符合HTML在实际HTML页面中呈现的方式。它甚至包括了适当的HTML缩进,并且仍然使用新的行字符来正确地格式化输出的HTML。

结论

虽然我没有详细解释这个集合中涉及的每一个概念,但我希望这个列表为初级和中级编码人员提供了一些相当高级的JavaScript策略的概述,他们可以在未来的项目或实验中实现。请随意评论我提到的任何高级JavaScript概念,以及您在自己的应用程序中使用它们的一些具体方式。

相关内容

WebFX职业

加入我们的使命,为全球各地的企业提供业界领先的数字营销服务,同时建立您的个人知识和个人成长。

我们招聘! 视图30 +职位空缺!