Nodejs聊聊JS语言是如何从前端移到后台的

Nodejs聊聊JS语言是如何从前端移到后台的

在cnodejs上看得比较多的主要是安装、配置、框架集成等话题。很少谈及js语言本身的讨论,今天我来起个头,希望大家能积极参与,碰撞出一些火花。

出处

js的出处大家都知道,先是netscape给自己浏览器写的,后来标准化了,集成到ECMA标准集中,成为ECMAScript 262标准,后来伴随html5制定了265版本。 师出同门的还有flex 所用的action script, 和photoshop所用的脚本,最近还听说有些硬件也用上了js。所以,大家今后其实还可以到这些领域去施展一下拳脚。

js起什么作用?

js 首先是一种计算机语言,其最核心的功能是:

  1. 按逻辑执行程序
  2. 操控数据
  3. 输入/输出

其次才是它的语法特性(比如OOP)、执行特性(比如异步)、易用性(比如自动内存管理)。 就其核心功能而言,js跟其它任何一门语言都无差别。

js的哪些特性是专为浏览器设计的?

js在浏览器中的运行,运行环境上下文是由浏览器程序赋予的,即window对象。因此,浏览器中运行时,this即是指window。 js对浏览器的主要用途有二:

  1. 实现DOM标准。如构造及保存节点树、提供访问和操控方法、响应节点事件(mouseOver, click…)
  2. 与浏览器环境交互。如与窗口对象(Window)、Location、History、Navigator、Screen交互

上面第1点中的事件问题一定要注意。我也是直到今天才知道这是DOM标准的一部分,而javascript当初为了实现这个标准,将响应事件的的能力内化在了语言中。也就成了后来大家所津津乐道的一大特性。其实,任何一种需要操控UI的语言都需要具备这种能力,或者通过别的方法变相实现这种能力(比如线程)。而那些不需要处理UI的语言就没怎么考虑过这个问题,如php, ruby, python, java,这些语言对事件的响应几乎都是通过线程实现。但javascript是单线程的,无法启动新线程,因此事件就成了变相多线程方式。

移植到浏览器以外的环境执行需要具备什么条件?

我以前不知道浏览器有webkit和V8的时候,以为浏览器是一个整体性的,不可分割的软件。知道后,才发现原来浏览器内UI元素的管理和程序执行环境是分别由不同的引擎在支撑。 既然程序由专门的引擎(虚拟机)在支撑,那这个虚拟机就可以移出来。但是,脱离了浏览器的环境,移出来做什么呢? 当然是做些常规程序做的事情:像perl一样做系统管理脚本,或是像php/java那样做服务器,或者像C一样无所不能

  1. 但既然移出来到操作系统所提供的环境运行,那程序本身的存储方式很大可能性就是文件,因此,操作文件的功能也必不可少。既然可以操作程序源文件或执行文件,那普通文件也自然不在话下,很多文件可以用来做为数据源或存储结果。
  2. 进一步考虑文件操作。文件如何读入?读入后如何存储?无论是源代码这样的ASCII字符还是图片、视频、word文档这种非ASCII数据,要读进来,就需要具备Read()方法,存起来就需要Write()方法。而文件读写肯定不能一个字节一个字节的操作,所以,还需要有二进制数据的容器,Buffer就是干这个的。考虑到不同的CPU和操作系统,以及网络传输规范等情况,还需要对大端序和小端序的支持。
  3. 要做服务器,那就必须能够打开一个网络端口进行监听。因此,网络操作能力也需要具备,其实这也就是扩展一个跟操作系统间的接口而已。这在浏览器上也是可以的,但是没必要。
  4. 进一步考虑网络操作,网络不能向磁盘一样预先知道其确切的传输量。而是一个数据流,因此,需要一个流式的读写方法。
  5. js虽然是可响应事件的,但事件是为DOM设计的,比如绑定对象必须是DOM节点(非HTML),事件会向父节点传递(冒泡)。对于更为常规的编程,不需要这样的事件机制,并且需要脱离DOM规范的设计。因此,需要实现一个额外的事件管理器。这就是NodeJs中的Event Class。
  6. 有时需要调用那些成熟软件,就需要跟安装在操作系统上的其它程序交互,通过在操作系统提供的shell环境,发起shell指令调用其它程序。这就是NodeJs中OS模块的作用。

总结一下,需要移出来到操作系统的大环境中运行,需要以下特性:

  1. 文件操作
  2. 流式读写
  3. 二进制数据容器
  4. 网络操作
  5. Event Class
  6. shell交互

如何操控DOM以外的对象?

  • 网络:
  • 数据库:
  • photoshop图层:
  • 文件:
  • 二进制数据:
  • 声音:
  • 串口:
  • USB设备:

总结:

无论哪种,它们都只是一个IO对象,这些对象都是二进制数据,或者是二进制数据驱动的。所以只要你能控制这些二进制数据,并能读取或写入到对应的地址或设备里去,那就可以操控它。对js而言,涉及两个问题:

  1. 二进制数据的操纵需要语言本身支持(其实几乎所有语言都支持二进制数据的,但js本身恰恰并未支持,所以NodeJs一上来就先解决了这个问题);
  2. 地址和设备的读写控制由操作系统管理,所以要额外添加一些接口来跟操作系统沟通。这也是NodeJs需要一个标准库的原因。

补充问题

  1. 标准库没涉及到的对象怎么办?比如遥控飞机、控制门锁、蓝牙通信、各类传感器数据获取等。这些设备的控制在标准库中没有,但属于操作系统可控的范围,因此,只要补充对应的操作库即可。这就是NodeJs留有C++接口的原因。
  2. 那些操作系统管不了的事情怎么办?比如photoshop图层、画笔、flex中的元素、动画等等。这些属于应用层之上的对象,就需要应用自己创建一个执行环境,并赋予执行上下文,定义各类对象和执行逻辑。这样就可以了。

跟其他语言有什么异同?

从最底层的运行逻辑上讲,js跟其它语言没有什么差异,都是以逻辑结构做为执行条件。 从执行环境层面来说,各种语言的执行顺序略有不同,有的语言是以顺序运行,有的靠触发,但根本上都是顺序执行的,只是执行的范围有所不同。因此,其执行是严格可预测的,而不能预测的只是事件发生的时间。

对JS应用的展望

js可以在浏览器上执行,也可以在服务器上执行,这是大家已经看到的。但其实它做为一种常规语言,可以做几乎任何事:

  • 做系统管理脚本。
  • 做普通GUI程序的控制语言。这需要扩展绘图模块,并在应用程序中集成js引擎。实际上现在linux上有个项目(Seed)就已经实现了,其图形库是GTK,控制语言使用javascript。
  • 做Android, ios平台上的普通app。实际上现在的phoneGap(Cordova)就是将webkit+js引擎预先集成到app中,开发者仅需像开发web一样开发即可。但这种app需要每个都集成一个webkit+v8(或其它js引擎)。更好的方式是整个大环境就是一个webkit+v8,然后每个app就只有相应的html, css, js代码即可,firefoxOS既是如此。要做手机app,则需要js引擎补充实现各种设备访问接口。如拨号、3D传感器、摄像头、GPS、蓝牙等。
  • 在带操作系统的微型PC上运行。比如前面帖子中有人编译到了openWRT上;还有一个控制auduino的NodeJs模块(名叫Johnny-Five)
  • 其它IO密集,但处理时效性要求高的领域里
  • 但也有例外,js也有不能做的事情:
    1. 单片机程序,或者实现一个裸机操作系统。因为js必须要一个虚拟机来运行,而虚拟机本身还不具备操作系统的功能。如设备管理、内存管理(这里可不是指自动垃圾回收机制,而是真正的物理内存)、任务调度(当然,单一功能的设备上,单线程的js无需理会这个需求)。
    2. 科学计算。(这个不知道我说的对不对,求指正)

由于时间有限,暂时写这么多。有空再补!也欢迎大家留言交流!


13 回复

Nodejs聊聊JS语言是如何从前端移到后台的

在cnodejs上看得比较多的主要是安装、配置、框架集成等话题。很少谈及js语言本身的讨论,今天我来起个头,希望大家能积极参与,碰撞出一些火花。

出处

js的出处大家都知道,先是Netscape给自己浏览器写的,后来标准化了,集成到ECMA标准集中,成为ECMAScript 262标准,后来伴随HTML5制定了265版本。师出同门的还有Flex所用的ActionScript,和Photoshop所用的脚本。最近还听说有些硬件也用上了js。所以,大家今后其实还可以到这些领域去施展一下拳脚。

JS起什么作用?

js首先是一种计算机语言,其最核心的功能是:

  • 按逻辑执行程序
  • 操控数据
  • 输入/输出

其次才是它的语法特性(比如OOP)、执行特性(比如异步)、易用性(比如自动内存管理)。就其核心功能而言,js跟其它任何一门语言都无差别。

JS的哪些特性是专为浏览器设计的?

js在浏览器中的运行,运行环境上下文是由浏览器程序赋予的,即window对象。因此,浏览器中运行时,this即是指window。js对浏览器的主要用途有二:

  1. 实现DOM标准。如构造及保存节点树、提供访问和操控方法、响应节点事件(mouseOver, click…)。
  2. 与浏览器环境交互。如与窗口对象(Window)、Location、History、Navigator、Screen交互。

上面第1点中的事件问题一定要注意。我也是直到今天才知道这是DOM标准的一部分,而javascript当初为了实现这个标准,将响应事件的能力内化在了语言中。这也成了后来大家所津津乐道的一大特性。其实,任何一种需要操控UI的语言都需要具备这种能力,或者通过别的方法变相实现这种能力(比如线程)。而那些不需要处理UI的语言就没怎么考虑过这个问题,如PHP, Ruby, Python, Java,这些语言对事件的响应几乎都是通过线程实现。但JavaScript是单线程的,无法启动新线程,因此事件就成了变相多线程方式。

移植到浏览器以外的环境执行需要具备什么条件?

我以前不知道浏览器有WebKit和V8的时候,以为浏览器是一个整体性的,不可分割的软件。知道后,才发现原来浏览器内UI元素的管理和程序执行环境是分别由不同的引擎在支撑。既然程序由专门的引擎(虚拟机)在支撑,那这个虚拟机就可以移出来。但是,脱离了浏览器的环境,移出来做什么呢?

当然是做些常规程序做的事情:像Perl一样做系统管理脚本,或是像PHP/Java那样做服务器,或者像C一样无所不能

但既然移出来到操作系统所提供的环境运行,那程序本身的存储方式很大可能性就是文件,因此,操作文件的功能也必不可少。既然可以操作程序源文件或执行文件,那普通文件也自然不在话下,很多文件可以用来做为数据源或存储结果。

const fs = require('fs');

// 读取文件
fs.readFile('./example.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

// 写入文件
fs.writeFile('./output.txt', 'Hello World!', err => {
    if (err) throw err;
    console.log('File is written successfully!');
});

如何操控DOM以外的对象?

  • 网络:Node.js提供了内置的http模块,可以创建Web服务器。
const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});
  • 数据库:使用第三方库如mongoose连接MongoDB。
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true });

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    console.log('Connected to MongoDB');
});

总结

无论哪种,它们都只是一个IO对象,这些对象都是二进制数据,或者是二进制数据驱动的。所以只要你能控制这些二进制数据,并能读取或写入到对应的地址或设备里去,那就可以操控它。对js而言,涉及两个问题:

  1. 二进制数据的操纵需要语言本身支持(其实几乎所有语言都支持二进制数据,但js本身恰恰并未支持,所以NodeJs一上来就先解决了这个问题);
  2. 地址和设备的读写控制由操作系统管理,所以要额外添加一些接口来跟操作系统沟通。这也是NodeJs需要一个标准库的原因。

补充问题

  1. 标准库没涉及到的对象怎么办?比如遥控飞机、控制门锁、蓝牙通信、各类传感器数据获取等。这些设备的控制在标准库中没有,但属于操作系统可控的范围,因此,只要补充对应的操作库即可。这就是NodeJs留有C++接口的原因。
  2. 那些操作系统管不了的事情怎么办?比如Photoshop图层、画笔、Flex中的元素、动画等等。这些属于应用层之上的对象,就需要应用自己创建一个执行环境,并赋予执行上下文,定义各类对象和执行逻辑。这样就可以了。

跟其他语言有什么异同?

从最底层的运行逻辑上讲,js跟其它语言没有什么差异,都是以逻辑结构做为执行条件。从执行环境层面来说,各种语言的执行顺序略有不同,有的语言是以顺序运行,有的靠触发,但根本上都是顺序执行的,只是执行的范围有所不同。因此,其执行是严格可预测的,而不能预测的只是事件发生的时间。

对JS应用的展望

js可以在浏览器上执行,也可以在服务器上执行,这是大家已经看到的。但其实它做为一种常规语言,可以做几乎任何事:

  • 做系统管理脚本。
  • 做普通GUI程序的控制语言。这需要扩展绘图模块,并在应用程序中集成js引擎。实际上现在Linux上有个项目(Seed)就已经实现了,其图形库是GTK,控制语言使用javascript。
  • 做Android, iOS平台上的普通app。实际上现在的PhoneGap(Cordova)就是将WebKit+js引擎预先集成到app中,开发者仅需像开发web一样开发即可。但这种app需要每个都集成一个WebKit+V8(或其他js引擎)。更好的方式是整个大环境就是一个WebKit+V8,然后每个app就只有相应的HTML, CSS, JS代码即可,FirefoxOS即是如此。要做手机app,则需要js引擎补充实现各种设备访问接口。如拨号、3D传感器、摄像头、GPS、蓝牙等。
  • 在带操作系统的微型PC上运行。比如前面帖子中有人编译到了OpenWRT上;还有一个控制Arduino的NodeJs模块(名叫Johnny-Five)。
  • 其它IO密集,但处理时效性要求高的领域里。

但也有例外,js也有不能做的事情:

  • 单片机程序,或者实现一个裸机操作系统。因为js必须要一个虚拟机来运行,而虚拟机本身还不具备操作系统的功能。如设备管理、内存管理(这里可不是指自动垃圾回收机制,而是真正的物理内存)、任务调度(当然,单一功能的设备上,单线程的js无需理会这个需求)。
  • 科学计算。(这个不知道我说的对不对,求指正)

由于时间有限,暂时写这么多。有空再补!也欢迎大家留言交流!


楼主看JS语言的角度高,我们这些晚辈只能不断的学习来开阔自己的眼界。持续关注该贴···

有如何实现异步编程的就好了

一知半解,但似乎很厉害的样子!

我的理解也不一定完全正确,若有错误,希望大家能够指正。这对我加深理解也是非常有帮助的!

好文。

实现语言基于环境很简单, 拿linux, 其本身已经提供了完备的文件、tcp http、磁盘… node api只需要依靠c语言建立操作linux api的内核, 并提供可编程接口即可。

那是操作层面的内容,这个今后另起文章再写。

关于事件那块不妥,事件的监听和响应只是一种设计模式:观察者模式,与线程并无关联。另外提到的几种语言中,我知道的,java和python都可以做客户端,那显然需要处理UI。

你说的是实现的层面,事件的实现方式都是通过你说的观察者模式实现的。 只是有些实现是在虚拟机层面,有些是在库层面。这个我需要进一步了解或者测试一下。 js的实现即是在虚拟机层面,所以在js这个语言特性中没有线程的概念。但java在运行过程中,其事件是通过EventQueue在库这一层面利用线程来实现事件监听和分发的。所以其事件机制完全依赖语言提供的线程。如果java是单线程语言,那就无法实现事件监听了。 谢谢你提出的意见!

写的不错

一句话,JS就是胶水,其他的东东是积木……

Nodejs聊聊JS语言是如何从前端移到后台的

出处

JavaScript最初是在Netscape的浏览器中开发的,后来被标准化为ECMAScript,成为了浏览器的核心脚本语言。随着HTML5的发展,JavaScript的功能和应用场景不断扩大,不仅仅局限于浏览器,还可以在服务器端运行。

JS起什么作用?

JavaScript作为一种计算机语言,其核心功能包括:

  • 按逻辑执行程序
  • 操控数据
  • 输入/输出

这些功能与任何其他语言并无本质区别。

JS的哪些特性是专为浏览器设计的?

在浏览器中,JavaScript主要负责DOM操作和事件处理。例如:

document.getElementById('myButton').addEventListener('click', function() {
    console.log('Button clicked');
});

这段代码展示了如何绑定一个点击事件处理函数。

移植到后台环境的必要条件

为了让JavaScript能够在后台环境中运行,我们需要提供一系列的API,使JavaScript可以进行文件操作、网络通信、事件管理等。Node.js就是这样一个实现了这些功能的平台。

示例代码:文件操作

在Node.js中,我们可以使用fs模块来操作文件:

const fs = require('fs');

// 读取文件
fs.readFile('./example.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

// 写入文件
fs.writeFile('./example.txt', 'Hello World!', (err) => {
    if (err) throw err;
    console.log('Data written to file');
});

示例代码:网络操作

使用http模块创建一个简单的HTTP服务器:

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
});

server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});

总结

JavaScript从浏览器到服务器的迁移主要依赖于Node.js提供的丰富API。这些API使得JavaScript不仅可以处理传统的Web前端任务,还可以进行文件操作、网络通信、事件管理等后台任务。因此,JavaScript在前后端都能发挥强大的功能。

通过以上示例代码,我们可以看到,JavaScript不仅能在浏览器中实现动态交互,也能在服务器端处理复杂的逻辑和任务。未来,随着Node.js生态系统的不断完善,JavaScript的应用场景将进一步扩大。

回到顶部