老生常谈的闭包:
书上给的基础概念是‘闭包是指的有权访问另一个函数作用域中的变量的函数’,这么看所有function都是闭包了?(事实似乎也确是如此)
一篇充满善意的闭包ppt...:
https://app.box.com/shared/elkumrpfng
发现了一篇讲解得清楚到丧心病狂的文章:
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
来玩下阮老师出的思考题:(书中将闭包也讲了这两个例子)
<span style="font-size:18px;"> var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());</span>
答案是 The Window, 即在alert中执行 getNameFunc的时候this将指向全局, 而全局的name为The Window.
如果在全局中使用'use strict'则会导致error.
那么如何可以alert出My Object呢?我只想到了不用闭包的方法:
<span style="font-size:18px;"> var name = "The Window";
var object = {
name : "My Object",
getNameFunc :
function(){
return this.name;
}
};
alert(object.getNameFunc.call(object));</span>
其实这么做跟闭包没啥关系了...
第二道题:
<span style="font-size:18px;"> var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());</span>
这次可以正确的输出 My Object了, 因为这一次我们利用var保存了指向object的this,这不正好就是文章里讲的:闭包让这些变量的值始终保存在内存中(另一个闭包的特性是可以使外部读取到函数内部的变量)。
另一道对概念理解很有用处的题:
http://web.jobbole.com/84723/
<span style="font-size:18px;">//第十三题</span>
<span style="font-size:18px;">for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', function(){ console.log(i); });
document.body.appendChild(btn);
}</span>
问题是如果点击这5个button都会发生什么事儿, 目前这种代码情况是输出都是4,原因嘛,因为callback这个时候里面的i是4了。 想要每次循环都把这个i保存下来的话就需要用到闭包了,
for (var i = 0; i < 5; i++) {
(function () {
var haha = i;
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', function(){ console.log(haha); });
document.body.appendChild(btn);
})();
}
for (var i = 0; i < 5; i++) {
(function (i) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', function(){ console.log(i); });
document.body.appendChild(btn);
})(i);
}
第一种方法写起来还是比第一种要顺手,因为前面学到说变量会被保存起来,这么看来参数也会被保存起来啊???
ES6有什么不同?
由于去年年底才入行,那时已经进入了ES6时代,所以对ES6完全不敏感,这次来做一个小小的总结:
http://www.mamicode.com/info-detail-952851.html
Arrow Function: () => {} 说点儿啥好呢...
类的支持:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
http://book.mixu.net/node/ch6.html
let const:
比较特别的var, 之后在特定范围中才可以使用. const则是拿来定义常量
Promise:
http://caniuse.com/ ---> check we can use the API with specific browser
https://www.youtube.com/watch?v=g90irqWEqd8
说到底,Promise主要有三个状态,pending, fufilled and rejected, pending可以变为fufilled or rejected,
var promise = foo(){}
promise.then(function () {});
promise.catch(function() {});
0r -->
promise.then(function (){}).catch(function (err) {});
还可以让他链状执行:
promise.then(function () { return foo(1)}).then(function(){return foo(2)}).then(function () {}).catch (function(err){..});
Error handling is pretty convenient.
Promise.all([
foo(1),
foo(2),
foo(3)
]).then(function (values) {
var a = values[0];
var b = values[1]; // 但是先后不能保证!
})
<span style="font-size:18px;">var promise = new Promise (function (resolve, reject) {
resolve('resolved solution');
})
promise.then(function(result){
console.log('Can I get the solution?', result);
}).catch(function (err) {
console.error('ERR', err);
})</span>
注意上述代码中,resolve 和 reject可以改成你喜欢的word, 不过为了可读性,使用 resolve 和 reject比较好.
还有个很困扰的问题,这么看
promise和setTimeout的执行机制有何不同?
http://www.zhihu.com/question/36972010
如果想弄清楚这里,还有个必须弄懂event loop:
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
有点深奥,整理一下我能看得懂的部分:
首先,代码是这样的,
<span style="font-size:18px;">setTimeout(function(){console.log(4)},0);
new Promise(function(resolve){
console.log(1)
for( var i=0 ; i<10000 ; i++ ){
i==9999 && resolve()
}
console.log(2)
}).then(function(){
console.log(5)
});
console.log(3);</span>
结果是 1 2 3 5 4就算都是异步执行,也存在两种任务分类:macro task 以及 micro task, 在挂起时,javascript会把任务分别塞到这两个task queues中,执行过程为:首先从macro task中取出第一条任务,然后执行micro task中的所有任务,再执行macro task中当前的第一条任务,再执行所有micro task中的任务,周而复始。
macro task: script的整体代码,setInterval, setTimeout, setImmediate, I/O, UI rendering
micro task: process.nextTick, Promises, Object.observe, MutationObserver.
这里注意一点, script虽然放在异步里看起来怪怪的,因为它不应该是同步执行吗?但,如果把script拆分成许多小块,来看,那它其实也是‘异步’得了,只不过一个块状内的script会同步执行。
HTML的加载问题:
http://blog.csdn.net/xifeijian/article/details/10813339
IE的html下载和渲染是同时进行的,而且都是从上到下。 当遇到语义解释性的标签嵌入文件(js css)时,会开启新的connections来下载,下载完毕后才进行解析(阻塞下载, 之所以这样是因为JS中有可能会对DOM结构进行改写,在这种情况下,就需要重构DOM树)
为了更快的加载,减少inline javascript以及inline css的数量,减少不必要的comments 空格之类的东西,尽量合并js css文件,可以利用localStorage, sessionStorage来缓存数据.
This的问题:
this指向调用函数的对象,如果该函数被作为某个对象的方法调用则指向该对象,若被构造函数调用的话就指向被new出来的这个对象,apply/call的话则指向参数作用域(没有的话指向全局)。
<span style="font-size:18px;">var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1); </span>
输出是10 和 2, 分析原因为:fn是在window下被声明的,因此在obj.method调起的时候,它其实也是调用的window.fn(); 而对于arguments[0](), arguments本身是个array, 因此利用此来调起fn的时候,this将指向这个object(或者叫array),所以结果是 2, 即这个array的长度为2.