每天积累一丢丢(Wed, 5 May 2016)

来源:互联网 发布:淘宝卖家每天必做的事 编辑:程序博客网 时间:2024/04/30 14:58

老生常谈的闭包:

书上给的基础概念是‘闭包是指的有权访问另一个函数作用域中的变量的函数’,这么看所有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.












1 0
原创粉丝点击