Node.js生手必得明白的4个JavaScript概念

3.模块

如果你曾经接触过Java中的包,那么Node.js中的模块也没有什么不同。如果没有,那么也不用担心。模块是包含特定目的代码的简单的JavaScript文件。模块模式用来使你的代码易于导航和使用。要使用模块属性,你需要在JavaScript文件中需求它,很像在Java类中导入包。

node.js中有两种类型的模块。

核心模块——这些模块是用Node.js库预编译过的。核心模块的目的是提供开发者经常发生和重复的代码段,这些代码段如果不可用的话,会导致开发者陷入不得不一次又一次地写相同代码的处境。一些常见的核心模块是HTTP,URL,EVENTS,FILE
SYSTEM,等等。

用户定义模块——用户定义模块是开发人员在应用程序内创建用于特定目的的模块。当核心模块不能满足期望功能的时候就需要用户定义模块。

模块通过require函数提取。如果它是一个核心模块,那么参数仅仅是模块的名称。如果它是一个用户自定义模块,那么参数就是该模块在文件系统中的路径。例如:

// extract a core module like this
var http = require('http);
// extract a user defined module like this
var something = require('./folder1/folder2/folder3/something.js');
// extract a core module like thisvar http = require;// extract a user defined module like thisvar something = require('./folder1/folder2/folder3/something.js');

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);
});

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

您可能感兴趣的文章:

  • Ubuntu中搭建Nodejs开发环境过程分享
  • node.js 开发指南 – Node.js 连接 MySQL 并进行数据库操作
  • 使用Nodejs开发微信公众号后台服务实例
  • 我用的一些Node.js开发工具、开发包、框架等总结
  • node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
  • nodejs开发环境配置与使用
  • windows8.1+iis8.5下安装node.js开发环境
  • AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
  • 最流行的Node.js精简型和全栈型开发框架介绍
  • nodejs开发微博实例

本文为开发者总结了4个Node.js要点。 1. 非阻塞(Non-blocking)或异步I/O
由于Node.js一个服务器端框架,…

1.非阻塞或异步I/O

由于Node.js是一种服务器端框架,所以它的一个主要工作就是处理浏览器请求。在传统的I/O系统中,当前请求只有当先前请求的响应(HTML页面)已到达才会发出。这就是为什么它被称为阻塞I/O。服务器阻塞其他请求是为了处理当前的请求,而这会导致浏览器的等待。

Node.js不遵循I/O的这个原则。如果一个请求需要花费较长时间,那么Node.js会发送请求到事件循环(event
loop)中,并继续在调用栈(call
stack)中处理下一个请求。一旦未决请求完成处理,它就会告诉Node.js,并将响应渲染在浏览器上。

用一个虚拟的例子来理解这一点:

阻塞I / O

// take order for table 1 and wait...
var order1 = orderBlocking(['Coke', 'Iced Tea']);
// once order is ready, take order back to table.
serveOrder(order1);
// once order is delivered, move on to another table.
// take order for table 2 and wait...
var order2 = orderBlocking(['Coke', 'Water']);
// once order is ready, take order back to table.
serveOrder(order2);
// once order is delivered, move on to another table.
// take order for table 3 and wait...
var order3 = orderBlocking(['Iced Tea', 'Water']);
// once order is ready, take order back to table.
serveOrder(order3);
// once order is delivered, move on to another table.

在这个餐厅例子中,服务员给出菜单,等待订单完成,然后再回到餐桌根据菜单上菜。在当前客户点菜时,服务员就在旁边等待,不接受其他客户的菜单。

非阻塞I / O

// take order for table 1 and move on...
orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){
  return serveOrder(drinks);
});
// take order for table 2 and move on...
orderNonBlocking(['Beer', 'Whiskey'], function(drinks){
  return serveOrder(drinks);
});
// take order for table 3 and move on...
orderNonBlocking(['Hamburger', 'Pizza'], function(food){
  return serveOrder(food);
});

在这个例子中,服务员获得菜单,并告知厨师,然后返回取另一份菜单。在完成第一个菜单进程中,他既按照顺序给当前顾客上菜,也接受来自其他客户的点单。服务员不会因为阻塞来自于其他客户的点菜而浪费时间。

每个JavaScript对象被链接到一个来自于它可以继承属性的原型对象。原型类似其他OO语言中的类,但不同的是,它们本身也是对象。每一个对象都链接到Object.prototype,而Object.prototype自带JavaScript预定义。

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

Node.js开发者必须了解的4个JS要点,node.jsjs

本文为开发者总结了4个Node.js要点。

1. 非阻塞(Non-blocking)或异步I/O

由于Node.js一个服务器端框架,所以它主要工作之一是处理浏览器请求。在传统的I/O系统中,每个请求的发出都是在上一请求到达之后才发出的。所以这被称为阻塞(blocking)I/O。服务器会阻挡其它的请求以处理当前请求,从而导致浏览器等待。

Node.js不以这种方式来进行I/O处理。如果一个请求需要长时间处理,Node.js会把该请求发送给一个事件循环(event
loop),然后继续处理在调用堆栈(call
stack)中的下一请求。当延后请求处理完毕时,它会告知Node.js同时浏览器会做出响应反馈。

以下使用一个事例来说明。

Blocking I/O

// take order for table 1 and wait...
var order1 = orderBlocking(['Coke', 'Iced Tea']);
// once order is ready, take order back to table.
serveOrder(order1);
// once order is delivered, move on to another table.
// take order for table 2 and wait...
var order2 = orderBlocking(['Coke', 'Water']);
// once order is ready, take order back to table.
serveOrder(order2);
// once order is delivered, move on to another table.
// take order for table 3 and wait...
var order3 = orderBlocking(['Iced Tea', 'Water']);
// once order is ready, take order back to table.
serveOrder(order3);
// once order is delivered, move on to another table.

在这个餐馆例子中,服务员接收了菜单指令,等待饭菜处理,然后在饭菜处理完成后把饭菜端到桌子上。在服务员等候饭菜处理期间,他会拒绝其它客人的菜单指令。

Non-blocking I/O

// take order for table 1 and move on...
orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){
 return serveOrder(drinks);
});
// take order for table 2 and move on...
orderNonBlocking(['Beer', 'Whiskey'], function(drinks){
 return serveOrder(drinks);
});
// take order for table 3 and move on...
orderNonBlocking(['Hamburger', 'Pizza'], function(food){
 return serveOrder(food);
});

而在非阻塞模式下,服务员会告知厨师他接受到的菜单指令,然后去接收下一桌的指令。当第一桌饭菜处理完毕时,他会为那桌客人上菜,然后继续接收其它客人的指令。这样一来服务员不会由于阻塞指令而造成时间浪费。

2. 原型(Prototype)

原型在JS中是一个复杂的概念。在典型继承机制语言如Java或C++中,为了实现代码复用,你必须先创建一个类然后透过它来生成对象或透过类扩展来生成对象。但是在JS中没有类似的类概念。在JS中创建一个对象后,你需要透过它来扩展对象或创建新对象。这就叫做原型继承(prototypal
inheritence)。

每个JS对象都连接着一个原型对象并对并继承该对象的属性。每个对象与预定义JS的Object.prototype相联系。如果你透过obj.propName或obj[‘propName’>方式来查找对象属性但查找失败时,这时可尝试通过obj.hasOwnProperty(‘propName’)的方式进行查找,JS运行时会在在原型对象中查找属性。如果属性不存在于原型链中,那么将返回undefined值。

让我们用以下例子来进行说明:

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

当你创建了一个新对象,你必须选定一个以原型为基础的对象。在这里,我们为对象函数添加了一个create方法。create方法创建了一个以其它对象为原型的对象,并作为参数传入。

当我们变更新的对象时,它的原型是保持不变的。但是,当我们改动了原型对象,该变更会影响所有基于该原型的对象。

3. 组件(Modules)

如果你曾在Java中使用过包,那么Node.js的组件与之类似。如果没有,也不用担心;组件其实是简单的JS文件,用于实现特定的功能。组件模式的意义是让你工作得更加轻松。要使用组件,你必须像在JAVA中导入包一样进行JS文件导入。Node.js中有两种组件

核心组件(Core Modules)-
核心组件是结合Node.js库被预编译的。其目的是把程序员经常使用的功能开放出来,避免重复劳动。常见的核心组件有HTTP,
URL, EVENTS, FILE SYSTEM等等。

用户自定义组件(UserDefined Modules)-
用户自定义组件是提供给用户使用以实现具体功能的组件。当核心组件不足以满足程序员需要的时候,自定义组件就可派上用场了。

组件是通过require函数被抽取的。如果这是一个核心组件,那么参数就是组件名。如果这是一个用户自定义组件,那么参数就是其在文件系统中的组件路径。例如:

// extract a core module like this
var http = require('http);
// extract a user defined module like this
var something = require('./folder1/folder2/folder3/something.js');

4. 回调(Callbacks)

在JS中,函数是第一类对象。也就是说你可以像对常规对象那样对函数进行所有操作。例如指派函数到一个变量,把这些作为参数传给方法,把它们声明为对象的属性,甚至是把它们从函数里返回。

回调在JS中是异步函数,可以作为参数传递给其它函数或从其它函数里执行或返回而后再执行。这是回调的基本概念。

当我们把一个回调函数作为参数传递给另外的函数时,我们传递的仅仅是函数的定义;换言之,我们不会知道回调函数的执行时间。这完全依赖于回调函数机制。它会在稍后某个时间点进行回调调用。这是Node.js的非阻塞或异步行为的基本概念,可用下例进行说明:

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

这是一个最简单的调用。我们把一个匿名函数作为参数进行传递,作用是为setTimeout函数进行控制台的输出记录登记。因为这仅仅是个函数定义,我们不知道函数何时会被执行。这取决于setTimeout函数的second参数,即2S后。

首先,second记录语句记录了对控制台的输出,2S后,在回调函数中的记录语句记录了输出的内容。

// output
hello
world

写在最后

以上4点对Node.js开发者来说是要彻底理解和掌握的,建议多动手来好好体会这4个要点的含义。

4.回调函数

在JavaScript中,函数被认为是第一类对象。这意味着你可以对这些函数做所有可对常规对象做的操作。你可以赋值函数给变量,作为参数传递函数给方法,作为对象属性声明函数,甚至从函数返回函数。

回调函数是JavaScript中的匿名函数,它可以作为参数传递给其他函数,要么被执行或返回自函数稍后执行。这是回调函数——这个使用最广的函数编程范式的基础。

当我们将回调函数作为参数传递给另一个函数的时候,我们只能传递函数定义……换言之就是,我们不知道这个回调函数什么时候会执行。这完全取决于调用函数的机制。它会在以后的某个时间点“回调”,因此而得名。这也是非阻塞或Node.js异步行为的唯一基础,如下例所示。

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

这是回调函数最简单的例子之一。我们将一个匿名函数作为一个参数传递,这个参数只需在控制台上记录一些输出到setTimeout函数。它是唯一的函数定义,但是不知道何时执行。这需要经过2秒后,通过第二个参数,调用setTimeout函数来决定。

首先,第二个日志语句记录输出到控制台,然后,2秒钟后,回调函数中的日志语句记录输出。

// output
hello
world

上面这些就是Node.js新手必须知道的4个最重要的
JavaScript概念。你的看法呢?希望大家能够畅所欲言!

以上4条JavaScript概念是Node.js新手必须知的个最重要概念,越是基础的东西越是重要,大家一家要牢记

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

下面这四个基本概念是你想要掌握node.js所必需的。我会尽可能长话短说向大家介绍它们。

这是回调函数最简单的例子之一。我们将一个匿名函数作为一个参数传递,这个参数只需在控制台上记录一些输出到setTimeout函数。它是唯一的函数定义,但是不知道何时执行。这需要经过2秒后,通过第二个参数,调用setTimeout函数来决定。

四、回调

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

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

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

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

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

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

// output
hello
world

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

Node.js开发者必须熟悉的四个JavaScript概念
Node.js是一个服务器端的开发框架,它基于Google Chrome的V…

图片 1

// outputhelloworld

1、核心模块(Core Module)

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

这样一来,问题就解决了。一种语言就可以统治一切。而且,在整个应用程序中你只需要使用这一种语言。所以,我们需要深刻了解node.js。这就是本文的主题。

由于Node.js是一种服务器端框架,所以它的一个主要工作就是处理浏览器请求。在传统的I/O系统中,当前请求只有当先前请求的响应已到达才会发出。这就是为什么它被称为阻塞I/O。服务器阻塞其他请求是为了处理当前的请求,而这会导致浏览器的等待。

二、原型

在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方法创建了一个新对象,并且使用了另一个对象作为它的原型,并作为参数传递到新对象。

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

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

本文由码农网 –
小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

下面这4个基本概念是你想要掌握node.js所必需的。我会尽可能长话短说向大家介绍它们。

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

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

比如:

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

如果只需要知道一种编程语言就可以构建一个全栈的应用程序,是不是特别了不起?Ryan
Dahl为了把这个想法成为现实,创造了node.js。Node.js是建立在Chrome强劲的V8
JavaScript引擎上的服务器端框架。虽然最初是用C++编写的,但是应用程序通过JavaScript运行。

回调函数是JavaScript中的匿名函数,它可以作为参数传递给其他函数,要么被执行或返回自函数稍后执行。这是回调函数——这个使用最广的函数编程范式的基础。

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.原型

原型是JavaScript的一个复杂概念。不过因为在Node.js中你要多次用到原型,所以每个JavaScript开发人员都必须了解这个概念。

在实现经典继承的语言中,例如Java,或C
++,对于以代码重用为目的的语言,你首先必须写一个类,然后从该类创建对象或扩展该类。但是,在JavaScript中不存在类的概念。首先在JavaScript中创建一个对象,然后从这个对象中增加自己的对象,或创建新的对象。这就是所谓的原型传承和通过原型的实现。

每个JavaScript对象被链接到一个来自于它可以继承属性的原型对象。原型类似其他OO语言中的类,但不同的是,它们本身也是对象。每一个对象都链接到Object.prototype,而Object.prototype自带JavaScript预定义。

如果你通过obj.propName或 obj[‘propName’]
查找属性,而对象并不具有可通过
obj.hasOwnProperty(‘propName’)被检查的属性,那么JavaScript的运行时会在其原型对象中查找属性。如果原型对象也没有这样的属性,那么依次检查它的原型,直到找到匹配,或者到达Object.prototype。如果该属性不存在原型链,那么它会导致一个未定义的值。

通过下面的示例代码来理解这个概念:

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

当你创建一个新对象的时候,你必须选择一个应该是它的原型的对象。这里,我们添加了一个方法到Object 
function。该方法创建了一个使用另一个对象作为其原型的新对象,而原型作为参数传递给它。

当我们改变新对象的时候,它的原型不受影响。但是,当我们进行改变原型对象的时候,这些变化在所有基于该原型的对象上可见。

原型是一个复杂的概念。我将在另一篇文章中详细说明。

当你创建一个新对象的时候,你必须选择一个应该是它的原型的对象。这里,我们添加了一个方法到Object
function。该方法创建了一个使用另一个对象作为其原型的新对象,而原型作为参数传递给它。

一、非阻塞或异步I/O

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

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注