1、闭包性
js的每个函数都是一个个小黑屋,它可以获取外界信息,但是外界却无法直接看到里面的内容。将变量 n 放进小黑屋里,除了 b 函数之外,没有其他办法能接触到变量 n,而且在函数 a 外定义同名的变量 n 也是互不影响的,这就是所谓的增强“封装性”。这是缺点也是优点。应用场景:封装成私有成员变量,保证变量的安全性。如下代码,就是闭包的一种体现。
function a(){
var n=0;
function b(){
n++;
console.log(n);
}
return b;//很重要,将b于外界建立联系,保证n在a函数作用域内变化
}
var c=a();
c();//1
c();//2
2、代码执行的异步性
function a(){
var root;
d3.json("test.json",function(erro,json){
if(erro) return;
root=json;
});
console.log(root);//返回为undefine
}
a();
解决方法:ajax同步读取数据
var root;
function get(){
$.ajax({
//请求方式为get
type:"GET",
//json文件位置
url:"test.json",
//关闭异步
async:false,
//返回数据格式为json
dataType: "json",
//请求成功完成后要执行的方法
success: function(result){ root=result; console.log("success",root);},
fail:function(){console.log("fail");}
});
console.log("get",root);
}
get();
warining:Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
大概意思就是:在主线程里使用同步的ajax请求对用户体验有影响,所以不让用了
这个只是一个友好的提醒,在主线程上用同步的请求,会导致阻塞,必须得等到请求完毕并且有了返回(正确或错误),才能执行后面的代码,用户体验来说,就是卡了啊,这种就会出现在这种友好的提示。
搞清楚两个概念:
一个是Ajax请求分异步和同步2种模式。如果请求是同步的,在请求返回之前线程会一直阻塞,如果请求是在主线程中发起的,那就会造成整个浏览器阻塞。
另外一个就是主线程。这段话应该是针对HTML5说的,因为在HTML5以前,JavaScript是完全的单线程方式,主线程之外不存在其他线程。但在HTML5中增加了Worker对象,每个Worker运行在一个独立的线程中,Worker线程被阻塞一般是不会影响主线程和浏览器的。因此,如果非要使用同步的Ajax(这种情况应该很少见),那就放到Worker线程中吧,千万千万不要放到主线程里。
3、回调函数实现同步和异步
回调函数的概念:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。
回调函数的使用场合:
资源加载:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调,图片加载完成执行回调,AJAX等等。
DOM事件及Node.js事件基于回调机制(Node.js回调可能会出现多层回调嵌套的问题)。
setTimeout的延迟时间为0,这个hack经常被用到,settimeout调用的函数其实就是一个callback的体现
同步:
var c;
function a(cb){
console.log("c1",c); //第一个输出
cb();
console.log("c3",c); //第三个输出
}
var render=function(){
c=2;
console.log("c2",c);}; //第二个输出
a(render);
//c1 undefined
// c2 2
// c3 2
异步:
var c;
function a(cb){
console.log("c1",c); //第一个输出
setTimeout(cb,1000);
console.log("c2",c); //第二个输出
}
var render=function(){
c=2;
console.log("c3",c);}; //第三个输出
a(render);
//c1 undefined
//c2 undefined
//c3 2
参考:https://segmentfault.com/q/1010000003061980
#同步vs异步,阻塞vs非阻塞的概念
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。即不可以做其他事情。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。即可以做其他事情,互不影响。
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程
#eval只是一个普通的函数,只不过他有一个快速通道通向编译器,可以将string变成可执行的代码。
function b(){
for(i=0;i<91;i++)
{
eval("var xf"+i+" = 1;");
}
console.log(xf1);
}
b();