博客由WP迁移到Typecho
技术博客由WP成功迁移到了Typecho,使用体验好了不少,希望以后坚持写博。
技术博客由WP成功迁移到了Typecho,使用体验好了不少,希望以后坚持写博。
事件冒泡 -> 父级元素处理子元素的事件
cpu密集 -> web worker OR 事件委托 事件委托 -> 定时执行处理函数
DOM变动 -> 使用父级元素替代多个子元素的操作
GZIP -> 传输时压缩,抵达浏览器解压缩
避免js 对样式的直接改动 -> 使用css
减少js 对DOM的append -> 最后才append
js代码需要时才加载- > requirejs...
代码的混淆编译… -> webpack...
私有变量 -> 私有的,外部不可访问的变量和函数用 "_"
Getter 和 Setter -> 提供对变量的操作的接口
继承 -> 提供create接口 和 options 参数对class 的初始化
es5的新特性 -> forEach Object.defineProperty ...
资源: 资源是 REST 架构方式的核心概念。 每个资源都要使用唯一的 URL 表示。 某一类资源的集合也要有一个 URL。 API 还可以为某一类资源的逻辑子集定义集合 URL。 表示资源集合的 URL 习惯 在末端加上一个斜线,代表一种“文件夹”结构。
资源转换Json
client -> server: from_json server-> client: to_json
POST - PUT - DELETE —request with Token
蓝本和程序类似,也可以定义路由。 不同的 是,在蓝本中定义的路由处于休眠状态,直到蓝本注册到程序上后,路由才真正成为程序 的一部分。
寒假系统学习javascript的时候,写了一些简单的练习代码,先来看下面一段:
//闭包
var global_ten=10;
var sum;
function papa() {
var hundred_more=100;
sum=function(a,b){
return a+b+global_ten+hundred_more;
};
hundred_more=10000;
}
papa();//changed the hundred_more
console.log(sum(9,11));//hundred_more has changed
//访问保留环境中存在的i
var fns=[];
function definer(){
for(var i=0;i<5;i++){
fns.push(function(){
return i;
});
}
}
definer();
for (var i = 0; i < fns.length; i++) {
console.log(fns[i]());
};
//引入另一个作用域对象local_i
//() 立即函数 立即执行
var fns_ano=[]
function definer_ano(){
for(var i=0;i<5;i++){
fns_ano.push(function(local_i){
return function(){
return local_i;
}
}(i));
}
}
definer_ano();
for (var i = 0; i < fns_ano.length; i++) {
console.log(fns_ano[i]());
};
闭包是JavaScript 的高级特性,我们可以借助它来实现更多更复杂的效果来满足不同的需求。但是要注意的是因为把带有内部变量引用的函数带出了函数外部,所以该作用域内的变量在函数执行完毕后的并不一定会被销毁,直到内部变量的引用被全部解除。所以闭包的应用很容易造成内存无法释放的情况。
还有以下几个概念:
作用域
域(scope)是JavaScript 编程中一个非常重要的运行机制,在同步JavaScript 编程中它并不能充分引起初学者的注意,但在异步编程中,良好的作用域控制技能成为了JavaScript 开发者的必备技能。另外,作用域在JavaScript 内存管理中起着至关重要的作用。
作用域链
由于JavaScript 中,变量标识符的查找是从当前作用域开始向外查找,直到全局作用域为止。所以JavaScript 代码中对变量的访问只能向外进行,而不能逆而行之。
以上应有图,但是搜了一下网上资源也很多,在此不赘述 推荐:JavaScript内存优化
ps:关于系统学习javascript语言之建议--《javascript for php developers》。注: 以上内容《深入浅出node.js》也有详解。
近期从图书馆借来《深入浅出node.js》一书,拜读ing,今天晚上阅读了“异步I/O”一章。简要梳理一下:
I/O的阻塞与非阻塞
阻塞I/O完成整个获取数据的过程,而非阻塞I/O则不带数据直接返回,要获取数据,还需要通过文件描述符再次读取。
I/O的同步与异步
I/O的同步与异步出现在应用程序中。如果做阻塞I/O调用,应用程序等待调用的完成的过程就是一种同步状况。相反,I/O为非阻塞模式时,应用程序则是异步的。
异步I/O与轮询技术
当进行非阻塞I/O调用时,要读到完整的数据,应用程序需要进行多次轮询,才能确保读取数据完成,以进行下一步的操作。 轮询技术的缺点在于应用程序要主动调用,会造成占用较多CPU时间片,性能较为低下。现存的轮询技术有以下这些:
注:select 和epoll机制,在《tcp/ip网络编程》相关文章中已经介绍。
轮询满足了非阻塞I/O确保获取完整数据的需求,但对于应用程序而言,它仍然只能算作一种同步,因为依然需要等待I/O完全返回。等待期间,CPU要么用于遍历文件描述符的状态,要么用于休眠等待事件发生。
理想的异步I/O模型
理想的异步I/O应该是应用程序发起异步调用,而不需要进行轮询,进而处理下一个任务,只需在I/O完成后通过信号或是回调将数据传递给应用程序即可。
Node的异步I/O
事件循环
Node的执行模型实际上是事件循环。在进程启动时,Node会创建一个无限循环,每一次执行循环体的过程成为一次Tick。每个Tick过程就是查看是否有事件等待处理,如果有则取出事件及其相关的回调函数,若存在关联的回调函数则执行它们,然后进入下一个循环。如果不再有事件处理,就退出进程。
事件循环是一个典型的生产者/消费者模型。异步I/O、网络请求等则是事件的生产者,源源不断为Node提供不同类型的事件,这些事件被传递到对应的观察者那里,事件循环则从观察者那里取出事件并处理。
观察者
每个事件循环中有若干个观察者,通过向这些观察者询问来判断是否有事件要处理。事件循环是一个典型的生产者/消费者模型。在Node中,事件主要来源于网络请求、文件I/O等,这些事件有对应的网络I/O观察者、文件I/O观察者等,事件循环则从观察者那里取出事件并处理。
请求对象
从Javascript发起调用到内核执行完I/O操作的过渡过程中,存在一种中间产物,叫做请求对象。以最简单的Windows下fs.open()方法(根据指定路径和参数去打开一个文件并得到一个文件描述符)为例,从JS调用到内建模块通过libuv进行系统调用,实际上是调用了uv_fs_open()方法。在调用过程中,创建了一个FSReqWrap请求对象,从JS层传入的参数和方法都封装在这个请求对象中,其中我们最为关注的回调函数被设置在这个对象的oncompete_sym属性上。对象包装完毕后,将FSReqWrap对象推入线程池中等待执行。 至此,JS调用立即返回,JS线程可以继续执行后续操作。当前的I/O操作在线程池中等待执行,这就完成了异步调用的第一阶段。
执行回调
回调通知是异步I/O的第二阶段。线程池中的I/O操作调用完毕后,会将获取的结果储存起来,然后通知IOCP当前对象操作已完成,并将线程归还线程池。在每次Tick的执行中,事件循环的I/O观察者会调用相关的方法检查线程池中是否有执行完的请求,如果存在,会将请求对象加入到I/O观察者的队列中,然后将其当做事件处理。
在最后需要指出: Node通过事件驱动方式处理请求,可以省掉创建和销毁线程的开销,同时操作系统在调度任务时因为线程较少,上下文切换的代价也很低。即使在大量连接的情况下,Node也能有条不紊地处理请求。