Node.js开发者必须熟悉的四个JavaScript概念

简介: 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/50054087 Node.js开发者必须熟悉的四个JavaScript概念作者:chszs,未经博主允许不得转载。
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/50054087

Node.js开发者必须熟悉的四个JavaScript概念

作者:chszs,未经博主允许不得转载。经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs

Node.js是一个服务器端的开发框架,它基于Google Chrome的V8 JavaScript引擎构建。尽管Node.js自身是使用C++开发的,但是它使用JavaScript作为其应用语言。
Node.js有四个概念对于初学者非常重要,应该理解并掌握它们。如下:

一、非阻塞或异步I/O

由于Node.js是一个服务器端框架,因此它的主要工作之一就是处理来自浏览器的请求。在传统的I/O系统中,只有先前请求的响应返回来后,新的请求才能发出。这也就是为什么称之为阻塞I/O的通信。服务器阻塞了下一个到来的请求,然后处理当前的请求,直到请求处理完成,发出响应,再解除下一个到来的请求的阻塞。

Node.js不遵循上面的阻塞I/O通信原则。如果一个请求需要的处理时间较长,Node.js会把请求发送到事件循环中,然后在调用栈上处理下一个请求。一旦事件循环中的请求完成了处理,它会通知Node.js,Node.js会返回响应给浏览器。下面可以看一个例子:

1、阻塞式I/O

// 餐桌1,获取订单1
var order1 = orderBlocking(['Coke', 'Iced Tea']);
// 服务订单1
serveOrder(order1);
// 一旦订单服务完成,服务员去另一张餐桌
// 餐桌2,订单2
var order2 = orderBlocking(['Coke', 'Water']);
// 服务订单2
serveOrder(order2);
// 一旦订单服务完成,服务员去另一张餐桌
// 餐桌3,订单3
var order3 = orderBlocking(['Iced Tea', 'Water']);
// 服务订单3
serveOrder(order3);
// 一旦订单服务完成,服务员去另一张餐桌

上面的例子中,服务员在第一个餐桌获得订单,然后向订单提供服务,服务完成后,服务员立刻移动到下一张餐桌获得订单。订单是按时间顺序进行处理的,服务器仅仅是服务于订单和阻塞其它的订单。

2、非阻塞式I/O

// 在餐桌1取走交付的订单并移动到下一个餐桌
orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){
  return serveOrder(drinks);
});
// 在餐桌2取走交付的订单并移动到下一个餐桌
orderNonBlocking(['Beer', 'Whiskey'], function(drinks){
  return serveOrder(drinks);
});
//在餐桌3取走交付的订单并移动到下一个餐桌
orderNonBlocking(['Hamburger', 'Pizza'], function(food){
  return serveOrder(food);
});

在上面的例子中,服务员去获取订单并通知厨师,再去下一个餐桌。在第一个订单被处理期间,服务员移动到下一个餐桌去获取订单,服务员不阻塞订单。

二、原型

在JavaScript中,原型即Prototype,是一个比较复杂的概念。Node.js使用了原型的地方很多,因此每一个JavaScript开发者都应该熟悉这个概念。

像Java、C++等编程语言都实现了典型的继承,这有助于代码的重用。首先构建一个基类(作为对象的蓝图),然后从这个类创建对象或扩展这个类。

但是JavaScript语言没有这样的概念。首先在JavaScript中创建一个对象,然后扩展这个对象或者从这个对象中创建新的对象。这就是所谓的原型继承,它通过原型来实现。

每一个JavaScript对象都链接到一个原型对象,并且可以从原型对象中继承其属性。原型有点类似于面向对象语言中的类,但实际上是不同的,它们自身都是对象。每一个对象都链接到Object.prototype,它是JavaScript预定义的对象。

如果你在通过obj.propName或obj[‘propName’]来查看属性时,这个对象有没有这样的属性,可以通过obj.hasOwnProperty(‘propName’)来检查,JavaScript的运行时会查看原型对象中是否有这个属性。如果原型对象没有这样的属性,然后再依次检查此对象本身有没有这样的属性(有可能对象继承了几级),直到匹配到此属性。如果整个属性链都没有这样的属性,那么就会返回未定义的值。

用例子来说明这一点:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
var otherPerson = Object.create(person);

当创建了一个新对象时,你可以选择这个对象的原型。在上面的代码中,我们增加了一个Object函数的create方法。create方法创建了一个新对象,并且使用了另一个对象作为它的原型,并作为参数传递到新对象。

当我们修改了新对象,它的原型还保留原样,不受影响。但是如果我们要修改原型对象,那么就会影响到所有基于此原型对象的对象。

原型是一个很复杂的概念,需要继续深入。

三、模块

如果你熟悉Java语言的包Package概念,那么你会理解Node.js的模块这个概念,两者没什么不同。模块是简单的JavaScript文件,它包含了特定目的的代码。模块模式(Module Pattern)用于简化代码的组织和导航。要使用模块的属性,你必须在JavaScript中require导入它,与Java语言中的import导入相同。

Node.js中有两者类型的模块:

1、核心模块(Core Module)

核心模块包含了预编译到Node.js的库。核心模块的模板是向开发者提供经常出现和重复的代码片段,如果没有这些,那么开发者会陷入这些大量重复且冗长无趣的工作中。常见的核心模块包括:HTTP模块、URL模块、EVENTS模块、文件系统模块等。

2、用户定义的模块(User Defined Module)

用户定义的模块是开发者为了特定功能自己实现的模块。通常是核心模块不能满足所需的功能时开发的。用户定义的模块同样需要require导入。如果是核心模块,require导入只需传入模块名,而对于用户定义的模块,require导入还需要传入文件系统的路径。

比如:

// 导入核心模块
var http = require('http);
// 导入用户定义的模块
var something = require('./folder1/folder2/folder3/something.js');

四、回调

在JavaScript语言中,函数被认为是第一级的对象。这意味着开发者可以把函数当作是常规对象那样,做所有的操作。可以把函数赋值给一个变量,还可以把函数作为参数传递给方法,还可以把函数作为对象的属性,甚至可以从函数返回函数。

回调是JavaScript语言中的一种匿名函数,它可以作为参数传递给另一个函数,还可以在随后的函数执行中执行回调函数或返回回调函数。这是回调函数广泛使用的编程范式。

把回调函数作为参数传递给另一个函数时,我们只需传递函数定义,也即,我们无需知道回调函数什么时候得以执行。这完全取决于调用函数的机制,故以回调命名。回调函数是Node.js的非阻塞通信和异步处理的基础。

setTimeout(function() {
    console.log("world");
}, 2000)
console.log("hello");

这是最简单的回调函数的例子之一,我们把匿名函数当作参数传递给setTimeout函数,而匿名函数仅仅是在控制台输出日志“world”。由于这只是函数定义,我们并不知道它什么时候得以执行,执行取决于setTimeout函数的2000毫秒后输出。

故第二个日志语句先在控制台输出“hello”,然后等两秒后再输出回调函数定义的日志“world”。

// output
hello
world

理解以上四个概念有助于深入Node.js。

目录
相关文章
|
2月前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
51 1
|
11天前
|
JavaScript 前端开发
【JavaScript】——JS基础入门常见操作(大量举例)
JS引入方式,JS基础语法,JS增删查改,JS函数,JS对象
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
29天前
|
存储 JavaScript NoSQL
Node.js新作《循序渐进Node.js企业级开发实践》简介
《循序渐进Node.js企业级开发实践》由清华大学出版社出版,基于Node.js 22.3.0编写,包含26个实战案例和43个上机练习,旨在帮助读者从基础到进阶全面掌握Node.js技术,适用于初学者、进阶开发者及全栈工程师。
52 9
|
2月前
|
JavaScript 前端开发
Moment.js与其他处理时间戳格式差异的JavaScript库相比有什么优势?
Moment.js与其他处理时间戳格式差异的JavaScript库相比有什么优势?
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
84 1
|
2月前
|
JavaScript 前端开发 中间件
JS服务端技术—Node.js知识点
本文介绍了Node.js中的几个重要模块,包括NPM、Buffer、fs模块、path模块、express模块、http模块以及mysql模块。每部分不仅提供了基础概念,还推荐了相关博文供深入学习。特别强调了express模块的使用,包括响应相关函数、中间件、Router和请求体数据解析等内容。文章还讨论了静态资源无法访问的问题及其解决方案,并总结了一些通用设置。适合Node.js初学者参考学习。
50 1
|
2月前
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API
使用JavaScript和Node.js构建简单的RESTful API
|
4天前
|
JavaScript
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈