Js基础知识
2017-03-24 22:50
281 查看
npm install --save 与 npm install --save-dev 的区别
不会修改package.json
之后运行npm install命令时,不会自动安装msbuild
会在package.json的dependencies属性下添加msbuild
之后运行npm install命令时,会自动安装msbuild到node_modules目录中
之后运行npm install --production或者注明NODE_ENV变量值为production时,会自动安装msbuild到node_modules目录中
会把msbuild包安装到node_modules目录中
会在package.json的devDependencies属性下添加msbuild
之后运行npm install命令时,会自动安装msbuild到node_modules目录中
之后运行npm install --production或者注明NODE_ENV变量值为production时,不会自动安装msbuild到node_modules目录中
离线安装:
npm install --cache-min 9999999
安装nvm
首先下载nvm,这里我们需要使用Git,如果没有安装git,可以使用
输入命令
nvm安装node版本
Koa2 vs Flask
flask更适合做后端,因为flask的后端工具链更加成熟!!但koa2更能锻炼人。
ctx需要内置
this.methods的作用
是从第三方methods中的get获取的
http://ternjs.net/doc/manual.html
node.js写后端也是传输json数据,跟flask一样,但工具链不成熟(第三方,最重要是vim的跳转支持不成熟),总的来说没有flask做后端方便。但js语法比python语法友好多了,与C系语法更接近,再加上是前端不可或缺的语言,因此后端选择了js。
tern的配置不太可信!
term的配置是加载你每次打开的文件进行匹配,如果没有则不匹配。
property is enumerable javascript
总的来说
python适合数据分析建模,js适合大前端,c++适合高性能
基础:异步机制
本节介绍JavaScript异步机制,首先来看一个例子:
1. i在此处是for循环所在上下文环境的变量,有且只有一个i;
2. 循环结束时i==5;
3. JavaScript单线程事件处理器在线程空闲前不会执行下一事件。
需要真正明白以上三点,需要理解js的事件循环和并发模型。注意:回调和事件处理程序本质上并无区别,只是在不同情况下,不同的叫法。
事件循环流程:
1. 宿主环境为JavaScript创建线程时,会创建堆(heap)和栈(stack),堆内存储JavaScript对象,栈内存储执行上下文;(堆栈和队列的区别:1. 堆(heap):内存中某一未被阻止的区域,通常存储对象(引用类型); 2. 栈(stack):后进先出的顺序存储数据结构,通常存储函数参数和基本类型值变量(按值访问);
3. 队列(queue):先进先出顺序存储数据结构)
2. 栈内执行上下文的同步任务按序执行,执行完即退栈,而当异步任务执行时,该异步任务进入等待状态(不入栈),同时通知线程:当触发该事件时(或该异步操作响应返回时),需向消息队列插入一个事件消息;
3. 当事件触发或响应返回时,线程向消息队列插入该事件消息(包含事件及回调);
4. 当栈内同步任务执行完毕后,线程从消息队列取出一个事件消息,其对应异步任务(函数)入栈,执行回调函数,如果未绑定回调,这个消息会被丢弃,执行完任务后退栈;
5. 当线程空闲(即执行栈清空)时继续拉取消息队列下一轮消息(next tick,事件循环流转一次称为一次tick)。
以上可描述为如下:
JavaScript异步编程使得多个任务可以并发执行,而实现这一功能的基础是JavScript拥有一个基于事件循环的并发模型。
如上图,当执行栈同步代码块依次执行完直到遇见异步任务时,异步任务进入等待状态,通知线程,异步事件触发时,往消息队列插入一条事件消息;而当执行栈后续同步代码执行完后,读取消息队列,得到一条消息,然后将该消息对应的异步任务入栈,执行回调函数;一次事件循环就完成了,也即处理了一个异步任务。
再谈SETTIMEOUT(…0)
了解了JavaScript事件循环后我们再看前文关于setTimeout(...0)的例子就比较清晰了:
setTimeout(...0)所表达的意思是:等待0秒后(这个时间由第二个参数值确定),往消息队列插入一条定时器事件消息,并将其第一个参数作为回调函数;而当执行栈内同步任务执行完毕时,线程从消息队列读取消息,将该异步任务入栈,执行;线程空闲时再次从消息队列读取消息。
1. 在读取消息队列的消息时,得等同步任务完成,这个是需要耗费时间的;
2. 消息队列先进先出原则,读取此异步事件消息之前,可能还存在其他消息,执行也需要耗时;
所以异步执行时间不精确是必然的,所以我们有必要明白无论是同步任务还是异步任务,都不应该耗时太长,当一个消息耗时太长时,应该尽可能的将其分割成多个消息。
WEB WORKERS
每个Web Worker或一个跨域的iframe都有各自的堆栈和消息队列,这些不同的文档只能通过postMessage方法进行通信,当一方监听了message事件后,另一方才能通过该方法向其发送消息,这个message事件也是异步的,当一方接收到另一方通过postMessage方法发送来的消息后,会向自己的消息队列插入一条消息,而后续的并发流程依然如上文所述。
JavaScript异步实现
关于JavaScript的异步实现,以前有:回调函数,发布订阅模式,Promise三类,而在ES6中提出了生成器(Generator)方式实现。
https模块
什么是CA:
CA(Certificate Authority)是数字证书认证中心的简称,是指发放、管理、废除数字证书的机构。
CA的作用是检查证书持有者身份的合法性,并签发证书(在证书上签字),以防证书被伪造或篡改,以及对证书和密钥进行管理。
SSL证书中DN(Distiguish Name)识别名的结构:
遵循x.500标准,标识名的目的就是为每个网络实体提供一个唯一的名字。为了达到这一目的,DN有一种分层结构。一个DN由一些列的RDN(Relative distinguished name,相对标识名)构成。
RDN的乘此结构依次为:
C = US, ST = Beijing, L = Beijing, O = RTFM, OU = Consulting, CN = Eric
(C->Country, ST-> State or Provice Name, L->Locality Name, O->Organization, OU->Organization Unit, CN->Common Name)
创建自己的CA机构
为CA生成私钥:
创建服务器端证书
为服务器生成私钥
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem
这一步非常关键,你需要指定一份openssl.cnf文件。可以用这个[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = BeiJing
localityName = Locality Name (eg, city)
localityName_default = BeiJing
organizationName = Organization Name (eg, company)
organizationName_default = Teamsun
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Letfl
commonName = commonName (e.g. server FQDN or YOUR name)
commonName_default = LetFl
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = 127.0.0.1
IP.2 = 192.168.1.6
通过服务器私钥文件和CSR文件生成服务器证书
创建客户端证书
生成客户端私钥
生成客户端证书
测试
1. 使用server证书测试单向认证
1.1 打开窗口1启动server
2 使用server证书和客户端证书做双向测试
2.1 打开窗口1启动server。(带有Verify参数,强制要求client证书)
2.4 通过控制台可以双向发送消息。
HTTPS 服务器代码
Google Chrome,Mac OS X和自签名SSL证书
这里是如何让Chrome浏览器使用自签名SSL证书:
1. 在地址栏中,点击X的小锁。这将显示一个小信息屏幕。单击说明“证书信息”的按钮。
2. 单击并将图像拖动到桌面。它看起来像一个小证书。
3. 双击它。这将启动钥匙串访问实用程序。输入您的密码解锁。
4. 确保将证书添加到系统钥匙串,而不是登录钥匙串。点击“始终信任”,即使这似乎没有任何作用。
5. 添加完成后,双击它。您可能需要再次进行身份验证。
6. 展开“信任”部分。
7. “使用此证书时”设置为“始终信任”
而已!关闭钥匙串访问并重新启动Chrome,浏览器现在应该识别您的自签名证书。
这是我希望Google / Chromium很快修复的一件事,因为它不应该是困难的。自签名的SSL证书在商业世界中被使用* 很多,对于知道他们正在做什么的人来说,应该有一个更简单的方法来忽略这个错误,而不是复制证书并手动将它们添加到系统钥匙串。
ws第三方
websocket基于http实现,http基于tcp实现
最初不经过https,为ws。文件为main.js
1.1 运行服务端ws实例
1.2 运行客户端浏览器中的websocket实例
加入https,为wss。
对象查找
1. 避免对象的嵌套查询,因为JAVASCRIPT的解释性,a.b.c.d.e嵌套对象,需要进行4次查询,嵌套的对象成员会明显影响性能。
2. 如果出现嵌套对象,可以利用局部变量,把它放入一个临时的地方进行查询。
以npm安装msbuild为例:
npm install msbuild:
会把msbuild包安装到node_modules目录中不会修改package.json
之后运行npm install命令时,不会自动安装msbuild
npm install --save:
会把msbuild包安装到node_modules目录中会在package.json的dependencies属性下添加msbuild
之后运行npm install命令时,会自动安装msbuild到node_modules目录中
之后运行npm install --production或者注明NODE_ENV变量值为production时,会自动安装msbuild到node_modules目录中
npm install --save-dev:
会把msbuild包安装到node_modules目录中会在package.json的devDependencies属性下添加msbuild
之后运行npm install命令时,会自动安装msbuild到node_modules目录中
之后运行npm install --production或者注明NODE_ENV变量值为production时,不会自动安装msbuild到node_modules目录中
使用原则:
运行时需要用到的包使用--save,否则使用--save-dev。
产品模式用dependencies,开发模式用devDep。离线安装:
npm install --cache-min 9999999
安装nvm
首先下载nvm,这里我们需要使用Git,如果没有安装git,可以使用
sudo apt-get install git
git clone https://github.com/creationix/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`接下来,我们需要编辑我们的环境变量配置文件
cd vim .bashrc将source ~/.nvm/nvm.sh 添加进我们的.bashrc中,保存退出。
输入命令
source .bashrc将新增的nvm添加到系统中。
nvm -v#查看nvm版本
nvm安装node版本
nvm install 7.8.0 // 安装 nvm use 5.0 // 切换 nvm uninstall 7.8.0 // 删除 nvm alias default 5.0 // 更换默认 npm install -g react-native-cli // 安装 react-native-cli 模块至全局目录,安装完成的路径是 ~/.nvm/versions/node/v4.4.7/lib/react-native-cli
Koa2 vs Flask
flask更适合做后端,因为flask的后端工具链更加成熟!!但koa2更能锻炼人。
ctx需要内置
this.methods的作用
是从第三方methods中的get获取的
http://ternjs.net/doc/manual.html
node.js写后端也是传输json数据,跟flask一样,但工具链不成熟(第三方,最重要是vim的跳转支持不成熟),总的来说没有flask做后端方便。但js语法比python语法友好多了,与C系语法更接近,再加上是前端不可或缺的语言,因此后端选择了js。
tern的配置不太可信!
term的配置是加载你每次打开的文件进行匹配,如果没有则不匹配。
property is enumerable javascript
总的来说
python适合数据分析建模,js适合大前端,c++适合高性能
基础:异步机制
本节介绍JavaScript异步机制,首先来看一个例子:
for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 0); } console.log(i);应该明白最后输出的全是5:
1. i在此处是for循环所在上下文环境的变量,有且只有一个i;
2. 循环结束时i==5;
3. JavaScript单线程事件处理器在线程空闲前不会执行下一事件。
需要真正明白以上三点,需要理解js的事件循环和并发模型。注意:回调和事件处理程序本质上并无区别,只是在不同情况下,不同的叫法。
事件循环流程:
1. 宿主环境为JavaScript创建线程时,会创建堆(heap)和栈(stack),堆内存储JavaScript对象,栈内存储执行上下文;(堆栈和队列的区别:1. 堆(heap):内存中某一未被阻止的区域,通常存储对象(引用类型); 2. 栈(stack):后进先出的顺序存储数据结构,通常存储函数参数和基本类型值变量(按值访问);
3. 队列(queue):先进先出顺序存储数据结构)
2. 栈内执行上下文的同步任务按序执行,执行完即退栈,而当异步任务执行时,该异步任务进入等待状态(不入栈),同时通知线程:当触发该事件时(或该异步操作响应返回时),需向消息队列插入一个事件消息;
3. 当事件触发或响应返回时,线程向消息队列插入该事件消息(包含事件及回调);
4. 当栈内同步任务执行完毕后,线程从消息队列取出一个事件消息,其对应异步任务(函数)入栈,执行回调函数,如果未绑定回调,这个消息会被丢弃,执行完任务后退栈;
5. 当线程空闲(即执行栈清空)时继续拉取消息队列下一轮消息(next tick,事件循环流转一次称为一次tick)。
以上可描述为如下:
let async = function(sync, event) { // 1. // 2. sync(); let eventLoop = []; // 3. eventLoop.push(event); let i = eventLoop.length - 1; // 后进先出 while (eventLoop[i]) { // 4. event = eventLoop[--i]; if (event) { // 事件回调存在 event(); } // 否则事件消息被丢弃 // 5. } };并发模型(Concurrency model)
JavaScript异步编程使得多个任务可以并发执行,而实现这一功能的基础是JavScript拥有一个基于事件循环的并发模型。
let ele = document.querySelector('body'); function clickCb(event) { console.log('clicked'); } function bindEvent(callback) { ele.addEventListener('click', callback); } bindEvent(clickCb);针对如上代码我们可以构建如下并发模型:
如上图,当执行栈同步代码块依次执行完直到遇见异步任务时,异步任务进入等待状态,通知线程,异步事件触发时,往消息队列插入一条事件消息;而当执行栈后续同步代码执行完后,读取消息队列,得到一条消息,然后将该消息对应的异步任务入栈,执行回调函数;一次事件循环就完成了,也即处理了一个异步任务。
再谈SETTIMEOUT(…0)
了解了JavaScript事件循环后我们再看前文关于setTimeout(...0)的例子就比较清晰了:
setTimeout(...0)所表达的意思是:等待0秒后(这个时间由第二个参数值确定),往消息队列插入一条定时器事件消息,并将其第一个参数作为回调函数;而当执行栈内同步任务执行完毕时,线程从消息队列读取消息,将该异步任务入栈,执行;线程空闲时再次从消息队列读取消息。
let start = +new Date(); let arr = []; setTimeout(function() { console.log('time: ' + (new Date().getTime() - start)); }, 10);输出:
[master]$ node test.js time: 30在setTimeout异步回调函数里我们输出了异步任务注册到执行的时间,发现并不等于我们指定的时间,而且两次时间间隔也都不同,考虑以下两点:
1. 在读取消息队列的消息时,得等同步任务完成,这个是需要耗费时间的;
2. 消息队列先进先出原则,读取此异步事件消息之前,可能还存在其他消息,执行也需要耗时;
所以异步执行时间不精确是必然的,所以我们有必要明白无论是同步任务还是异步任务,都不应该耗时太长,当一个消息耗时太长时,应该尽可能的将其分割成多个消息。
WEB WORKERS
每个Web Worker或一个跨域的iframe都有各自的堆栈和消息队列,这些不同的文档只能通过postMessage方法进行通信,当一方监听了message事件后,另一方才能通过该方法向其发送消息,这个message事件也是异步的,当一方接收到另一方通过postMessage方法发送来的消息后,会向自己的消息队列插入一条消息,而后续的并发流程依然如上文所述。
JavaScript异步实现
关于JavaScript的异步实现,以前有:回调函数,发布订阅模式,Promise三类,而在ES6中提出了生成器(Generator)方式实现。
https模块
什么是CA:
CA(Certificate Authority)是数字证书认证中心的简称,是指发放、管理、废除数字证书的机构。
CA的作用是检查证书持有者身份的合法性,并签发证书(在证书上签字),以防证书被伪造或篡改,以及对证书和密钥进行管理。
SSL证书中DN(Distiguish Name)识别名的结构:
遵循x.500标准,标识名的目的就是为每个网络实体提供一个唯一的名字。为了达到这一目的,DN有一种分层结构。一个DN由一些列的RDN(Relative distinguished name,相对标识名)构成。
RDN的乘此结构依次为:
C = US, ST = Beijing, L = Beijing, O = RTFM, OU = Consulting, CN = Eric
(C->Country, ST-> State or Provice Name, L->Locality Name, O->Organization, OU->Organization Unit, CN->Common Name)
创建自己的CA机构
为CA生成私钥:
openssl genrsa -out ca-key.pem -des 1024通过CA私钥生成CSR:
openssl req -new -key ca-key.pem -out ca-csr.pem -subj "/C=CN/ST=Beijing/L=Beijing/O=Teamsun/OU=Teamsun"通过CSR文件和私钥生成CA证书:
openssl x509 -req -days 3650 -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem
创建服务器端证书
为服务器生成私钥
openssl genrsa -out server-key.pem 1024利用服务器私钥文件服务器生成CSR
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem
这一步非常关键,你需要指定一份openssl.cnf文件。可以用这个[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = BeiJing
localityName = Locality Name (eg, city)
localityName_default = BeiJing
organizationName = Organization Name (eg, company)
organizationName_default = Teamsun
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Letfl
commonName = commonName (e.g. server FQDN or YOUR name)
commonName_default = LetFl
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = 127.0.0.1
IP.2 = 192.168.1.6
通过服务器私钥文件和CSR文件生成服务器证书
openssl x509 -req -days 730 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf
创建客户端证书
生成客户端私钥
openssl genrsa -out client-key.pem 1024利用私钥生成CSR
openssl req -new -key client-key.pem -out client-csr.pem -config openssl.cnf
生成客户端证书
openssl x509 -req -days 365 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem
测试
1. 使用server证书测试单向认证
1.1 打开窗口1启动server
^o^$ 20:28:50 letfly@ [Js]$ openssl s_server -accept 10001 -key server-key.pem -cert server-cert.pem Using default temp DH parameters Using default temp ECDH parameters ACCEPT1.2 打开窗口2启动客户端
^o^$ 20:28:50 letfly@ [Js]$ openssl s_client -connect localhost:10001 CONNECTED(00000003) ... ...1.3 连接成功后在任意一个窗口输入字符串会传输到另外一个窗口回显。
2 使用server证书和客户端证书做双向测试
2.1 打开窗口1启动server。(带有Verify参数,强制要求client证书)
^o^$ 20:28:50 letfly@ [Js]$ openssl s_server -accept 10001 -key server-key.pem -cert server-cert.pem -Verify 52.2 打开窗口2启动客户端
^o^$ 20:28:50 letfly@ [Js]$ openssl s_client -connect localhost:10001 -cert client-crt.pem -key client-key.pem2.3 双向证书正确则连接成功,否则连接失败。
2.4 通过控制台可以双向发送消息。
HTTPS 服务器代码
const https = require('https'); const fs = require('fs'); let options = { key: fs.readFileSync('./server-key.pem'), ca: [fs.readFileSync('./ca-cert.pem')], cert: fs.readFileSync('./server-cert.pem'), requestCert: true, // 双向认证 rejectUnauthorized: true, }; https.createServer(options, function(req, res) { res.writeHead(200); res.end('hello world\n');}).listen(3000, '127.0.0.1');HTTPS 客户端代码
const https = require('https'); const fs = require('fs'); let options = { hostname: '127.0.0.1', port: 3000, path: '/', method: 'GET', key: fs.readFileSync('./client-key.pem'), cert: fs.readFileSync('./client-cert.pem'), ca: [fs.readFileSync('./ca-cert.pem')], rejectUnauthorized: true, }; options.agent = new https.Agent(options); let req = https.request(options, function(res) { console.log("statusCode: ", res.statusCode); console.log("headers: ", res.headers); res.setEncoding('utf-8'); res.on('data', function(d) { console.log(d); }); }); req.end(); req.on('error', function(e) { console.log(e); });
Google Chrome,Mac OS X和自签名SSL证书
这里是如何让Chrome浏览器使用自签名SSL证书:
1. 在地址栏中,点击X的小锁。这将显示一个小信息屏幕。单击说明“证书信息”的按钮。
2. 单击并将图像拖动到桌面。它看起来像一个小证书。
3. 双击它。这将启动钥匙串访问实用程序。输入您的密码解锁。
4. 确保将证书添加到系统钥匙串,而不是登录钥匙串。点击“始终信任”,即使这似乎没有任何作用。
5. 添加完成后,双击它。您可能需要再次进行身份验证。
6. 展开“信任”部分。
7. “使用此证书时”设置为“始终信任”
而已!关闭钥匙串访问并重新启动Chrome,浏览器现在应该识别您的自签名证书。
这是我希望Google / Chromium很快修复的一件事,因为它不应该是困难的。自签名的SSL证书在商业世界中被使用* 很多,对于知道他们正在做什么的人来说,应该有一个更简单的方法来忽略这个错误,而不是复制证书并手动将它们添加到系统钥匙串。
ws第三方
websocket基于http实现,http基于tcp实现
最初不经过https,为ws。文件为main.js
1.1 运行服务端ws实例
const WebSocketServer = require('ws').Server; let wsserver = new WebSocketServer({ port: 3000 }); wsserver.on('connection', function connection(ws) { ws.on('message', function incoming(message) { console.log('received: %s', message); }); ws.send('something'); });运行如下命令:
node main.js
1.2 运行客户端浏览器中的websocket实例
let socket = new WebSocket("ws://127.0.0.1:3000/"); socket.send('message');
加入https,为wss。
const fs = require('fs'); const https = require('https'); const WebSocketServer = require('ws').Server; // 单向认证 let options = { key: fs.readFileSync('./server-key.pem'), cert: fs.readFileSync('./server-cert.pem') }; let app = https.createServer(options, function(req, res) { res.end('Hello world\n'); }).listen(3000, '127.0.0.1'); let wsServer = new WebSocketServer({ server: app }); wsServer.on('connection', function connection(socket) { socket.on('message', function incoming(message) { console.log('received: %s', message); }); socket.send('something'); });
对象查找
1. 避免对象的嵌套查询,因为JAVASCRIPT的解释性,a.b.c.d.e嵌套对象,需要进行4次查询,嵌套的对象成员会明显影响性能。
2. 如果出现嵌套对象,可以利用局部变量,把它放入一个临时的地方进行查询。
相关文章推荐
- 后缀就扩展名为js的文件是什么文件[原创]_基础知识_脚本之家
- JavaScript入门教程(2) JS基础知识
- JavaScript学习笔记(一)——JS基础知识介绍
- JS中容易被忽略的基础知识
- js 一些基础知识
- JS基础知识总结
- JS的基础入门知识.
- 笔记 - JS易忘基础知识(一)(ECMAScript基础)
- JavaScript学习笔记(一)——JS基础知识介绍
- JavaScript就这么回事 (JS基础知识整理)
- JS基础知识
- JavaScript 入门基础知识 想学习js的朋友可以参考下
- JavaScript就这么回事 (JS基础知识整理)
- JavaScript就这么回事 (JS基础知识整理)
- JavaScript就这么回事 (JS基础知识整理)
- JavaScript就这么回事 (JS基础知识整理)
- JavaScript学习笔记(一)——JS基础知识介绍
- JavaScript就这么回事 (JS基础知识整理)
- 笔记 - JS易忘基础知识(二)(关于对象和继承)
- Js 基础知识(转)