【渗透】node.js经典问题
1.循环问题
当循环调用 require() 时,一个模块可能在未完成执行时被返回。
例如以下情况:
a.js:
exports.done = false;
const b = require('./b.js');
console.log('在 a 中,b.done = %j', b.done);
exports.done = true;
console.log('a 结束');
b.js:
console.log('b 开始');
exports.done = false;
const a = require('./a.js');
console.log('在 b 中,a.done = %j', a.done);
exports.done = true;
console.log('b 结束');
main.js:
console.log('main 开始');
const a = require('./a.js');
const b = require('./b.js');
console.log('在 main 中,a.done=%j,b.done=%j', a.done, b.done);
当 main.js 加载 a.js 时,a.js 又加载 b.js。 此时,b.js 会尝试去加载 a.js。 为了防止无限的循环,会返回一个 a.js 的 exports 对象的 未完成的副本 给 b.js 模块。 然后 b.js 完成加载,并将 exports 对象提供给 a.js 模块。
当 main.js 加载这两个模块时,它们都已经完成加载。 因此,该程序的输出会是:
$ node main.js
main 开始
a 开始
b 开始
在 b 中,a.done = false
b 结束
在 a 中,b.done = true
a 结束
在 main 中,a.done=true,b.done=true
需要仔细的规划, 以允许循环模块依赖在应用程序内正常工作.
2.原型继承问题
需要注意的是call、apply、bind方法都只能继承对象的方法,却不能对它们的原型进行拷贝或继承,为此我们一般使用混合的写法,使用原型链和(apply或者call)方法进行继承。
而在nodeJS中,util包提供了一个方法util.inherits(constructor, superConstructor)
所以就得如下,通过结合使用call和inherits才能将其完全拷贝:
function Girl(name){
this.name = name;
EventEmitter.call(this);
}
util.inherits(Girl,EventEmitter);
var girl = new Girl();
注意,不建议使用 util.inherits()。 请使用 ES6 的 class 和 extends 关键词获得语言层面的继承支持。 注意,这两种方式是语义上不兼容的。
constructor <Function>
superConstructor <Function>
从一个构造函数中继承原型方法到另一个。 constructor 的原型会被设置到一个从 superConstructor 创建的新对象上。
superConstructor 可通过 constructor.super_ 属性访问。
const util = require('util');
const EventEmitter = require('events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
MyStream.prototype.write = function(data) {
this.emit('data', data);
};
const stream = new MyStream();
console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true
stream.on('data', (data) => {
console.log(`接收的数据:"${data}"`);
});
stream.write('运作良好!'); // 接收的数据:"运作良好!"
例子:使用 ES6 的 class 和 extends:
const EventEmitter = require('events');
class MyStream extends EventEmitter {
write(data) {
this.emit('data', data);
}
}
const stream = new MyStream();
stream.on('data', (data) => {
console.log(`接收的数据:"${data}"`);
});
stream.write('使用 ES6');
【渗透】node.js经典问题的更多相关文章
- 从零开始学习渗透Node.js应用程序
本文来源于i春秋学院,未经允许严禁转载 0x01 介绍 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一 ...
- 教你通过Node.js漏洞完成渗透测试
本篇文章较为详细的讲述了通过node.js的已知漏洞来完成渗透测试的过程,介绍了node.js存在的漏洞可以在多种工具下的不同利用方式.因为我认为会对论坛部分web安全新手有所帮助,所以整理到论坛中. ...
- Node.js 教程 02 - 经典的Hello World
前言: Node.js的介绍.安装及配置,上一节都已经介绍过了,如果有不清楚的也可以留言或者直接问度娘. 本节: 本节主要以一个简单的例子简单体验一下Node.js,用到了两种方法.下面会介绍. 总之 ...
- 一段经典的node.js 数据库高并发实现
var proxy = new EventProxy();var status = "ready";var select = function(callback){ proxy.o ...
- node.js入门经典 初读笔记
2.1 npm是什么 npm(Node Package Manager)是Node.js的包管理器.它允许开发人员在Node.js应用程序中创建.共享并重用模块. 2.3 安装模块 npm insta ...
- Node.js 教程 01 - 简介、安装及配置
系列目录: Node.js 教程 01 - 简介.安装及配置 Node.js 教程 02 - 经典的Hello World Node.js 教程 03 - 创建HTTP服务器 Node.js 教程 0 ...
- <Node入门经典>读书笔记
最近在读<Node入门经典>, 之前没有做笔记, 今天开始把看过自己又写了的代码放这里以免忘记. express var express = require('express') var ...
- Node.js 教程 04 - 模块系统
前言: Node.js的模块系统类似于C/C++的文件引用,可以声明对象,也可以定义类 创建对象. 大家这么理解,就简单了. 定义: 为了让Node.js的文件可以相互调用,Node.js提供了一个简 ...
- 《深入浅出Node.js》第7章 网络编程
@by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...
随机推荐
- space sniffer
space sniffer 一款检测本地磁盘文件占用情况的工具,高效,快速.
- 吴裕雄--天生自然C语言开发:错误处理
#include <stdio.h> #include <errno.h> #include <string.h> extern int errno ; int m ...
- day43-线程概念
#1.进程:程序不能单独运行,要将程序加载到内存当中,系统为它分配资源才能运行,而这种执行的程序就是进程. #程序和进程的区别在于:程序是指令的集合,它是进程运行的静态描述文本:进程是程序的一次执行活 ...
- 四剑客(awk)
AWK AWK简介 虽然sed编辑器是非常方便自动修改文本文件的工具,但其也有自身的限制.通常你需要一个用来处理文件中的数据的更高级工具,它能提供一个类编程环境来修改和重新组织文件中的数据.这正是ga ...
- Sam format
reference:https://davetang.org/wiki/tiki-index.php?page=SAM @SQ SN:contig1 LN:9401 (序列ID及长度) 参考序列名,这 ...
- jquery JavaScript如何监听button事件
下面的html页面中有两个按钮 <div class="layui-tab-item layui-show"> <form class="layui-f ...
- python语法基础-面向对象-进阶-长期维护
############### @property定义属性 ############## # 所以对于定义属性你有好几种方式了和种类了,# 静态属性,动态属性, # property # ...
- linux系统--C语言程序开发的基本步骤(包含gcc的基本步骤)
1.使用vi或者vim编写程序文件 2.使用gcc把所有的源文件翻译成计算机认识的格式(编译) 3.使用./a.out作为命令执行得到的可执行文件 gcc编译器的工作步骤: 1.处理所有的预处理指令 ...
- file,path,uri互相转换
uri 转 file :File file = new File(new URI(uri.toString())); uri 转 path: Path path = Files.get(uri); f ...
- [LC] 242. Valid Anagram
Given two strings s and t , write a function to determine if t is an anagram of s. Example 1: Input: ...