JS作用域链
var n = 120;
function a()
{
var n = 100;
console.log(n);
}
a();//100
function b()
{
console.log(n);
}
b();//120
function c()
{
n = 100;
console.log(n);
}//100,注意:不加var是一个全局变量
/*function a()
{
var n = 120;
}
console(n);*/
在函数外部找函数内部变量,找不到
/*function a()
{
var n = 120;
}
console(n);//会报错!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
函数声明提升
/*var a = 18;
function f1(){
var b=9;
console.log(a); //undefined
console.log(b); //9
var a = '123';
}
f1();//从这个例子告诉我们函数声明提升,我们可以理解为执行f1()时,提前声明var a,b;当console.log(a);时,a已被定义未被赋值所以打印出undefined*/
闭包
因为js的函数都是一个个小黑屋,函数内部可以看到外部的变量,函数外部不能看到函数内部的变量。通俗易懂的理解就是函数内部的函数,来让外部引用内部的变量。这样做的好处是更好的实现函数封装。
function a()
{
var n = 0;
function b(){
console.log(n);
}
return b;
}
var c = a();
c(); // 0
匿名函数的传参
/*匿名函数var a = (funcion(){})();
第一个()中是匿名函数,如果有返回值,则把返回值赋给a;
第二个()中是要给匿名函数传递的参数;*/
var a = (function (){
var i = 1
i++;
return i;
})(a);
console.log(a);//a=2;
var b=5;
var a = (function(){
var i = 1;
return b+i;
})(b);
console.log(a);//a=6
var a = (function(){
var i=1;
return i;
})();
console.log(a);//a=1
var a = (function(){
var i=1;
})();
console.log(a);//a=undefind
this的用法
浏览器渲染机制
head中的脚本会在页面加载之前解析,可以保证脚本在任何调用之前被加载
body中会在页面加载完成之后读取,放在body部分的脚本通常被用来生成页面的内容。 因为加载js脚本会阻塞页面的加载,为了用户体验也为了脚本可以操作dom,一般放在body中, 浏览器解析html是从上到下的。 如果把js放在head里的话,则先被解析,但这时候body还没有解析,所以会返回空值。一般都会绑定一个监听,当全部的html文档解析完之后,再执行代码:
windows.οnlοad=function(){ }
理解一下这段JS代码执行结果
var num =20;
var obj= {
num:30,
fn: (function(num){
this.num*= 3;
num+=15;
var num=45;
return function() {
this.num*=4;
num+=20;
console.log(num);
}
})(num)
};
var fn=obj.fn;
fn();
obj.fn();
console.log (window.num) ;
console.log(obj.num) ;
</script>
console结果为???
因为执行fn()时return的匿名函数console.log的是num,这是谁指向他,他就调用谁的num。这时num为45.num+20=65。
所以当obj.fn()执行时,num+20=65+20=85。
第一次fn()执行,this指向的是window,this.num就为20,执行*3,再执行*4就为24。
第二次执行obj.fn(),this指向的obj,此时this.num为30。执行return里面*4,所以为120。
最后console.log(window.num);为240
console.log(obj.num);为120