接着上一篇文章接题目;

<script>
console.log(fn);//1》
function fn(){
console.log(1);
}
console.log(fn);//2》
var fn;
console.log(fn);//3》
function fn(){
console.log(2);
}
console.log(fn);//4》
var fn=10;
console.log(fn);//5》
//1、预解释阶段:预解释的时候 最后一步 var fn=10只是声明了,没有定义,相当于重复声明,是没有意义的
// 上次声明+定义是是fn(){console.log(2)},所以;在预解释的时候fn最终的是fn(){console.log(2);}这个方法;

//2、代码执行阶段:
// 第一个:console.log(fn); 是显示fn这个方法/函数;
//第二个:console.log(fn); 是显示fn这个方法/函数;没有变化,中间的fn(){console.log(2);}会直接跳过的;所以是没有变化;
//var fn;是声明一个fn。但是此时还是重复声明。还是没有对他进行覆盖的定义/赋值;
// 第三个:console.log(fn); 显示fn这个方法/函数,以内fn一直就没有变化过,一直是fn(){console.log(2);}这个方法;
//第四个:console.log(fn);解释同上,一直没有变化;
//这时候var fn=10;说明fn被重新赋值成10这个数字了;
//第五个:console.log(fn);此时相当于执行console.log(10);-->控制台输出的是10;

//3、答案是:
//<1>、function fn
//<2>、function fn
//<3>、function fn
//<4>、function fn
//<5>、10



</script>

fn和fn()的区别:

<script>
function fn(){
console.log(2);
}
//如果用fn 是把函数定义的部分返回出来;--》 会返回fn(),这个执行结果;
//如果用fn() 输出函数执行的返回结果;会出来2个一个是2,一个是undefined;(因为没有teturn)
</script>

如果加了returm,就会下面这样;

<script>
function fn(){
console.log(2);
return 10
}
//此时fn() 是返回两个值;一个是执行的值;一个是return的10;
</script>

函数的返回是可以随便写的,需要什么,就返回什么;

函数执行后可以有两个结果,一个是执行结果、一个是return结果;

在预解释的时候,如果发现名字重了,不重新声明了;但是如果要重新定义

自执行函数的——–

题目如下:

<script>
var name="china";
var age=5000;
;(function(name,age){//是自执行函数的两个形参变量;
//私有作用域中的私有变量name和age;和全局的age,name没有半毛钱关系;
//预解释前;先传参赋值:name:china;age:5000;
//函数预解释时候;age和name和传件来的冲突了,相当于无效预解释;
//代码执行的时候,var name和age会重新的定义;
console.log(name);//这个时候是形参赋值的时候传进来的。
var name="珠峰";//这个时候name会定义;私有的
var age=6;//私有的
console.log("name"+name+"age:"+age)
})(name,age)//把全局变量是name和age所储存的值传到函数中,给函数的两个形参变量;

//函数执行;
//1、如果有形参,先传参赋值;先给形参变量赋值;
//2、预解释;
//3、代码执行;

//结果是:china、name珠峰age:6
</script>

如果想变成name:china;age:5000;可以下面这样改:(禁止重新复制;)

<script>
var name="china";
var age=5000;
;(function(name,age){
console.log("name:"+name+"age:"+age)
})(name,age)
</script>

或者下面(禁止私有出现name和age;让它找全局的;)

<script>
var name="china";
var age=5000;
;(function(){
console.log("name:"+name+"age:"+age)
})()
</script>

还可以这么写:(通过window的属性名,直接的查找全局,通过指定范围直接查找;私有里可以用全局的;)

<script>
var name="china";
var age=5000;
;(function(name,age){
var name="珠峰";
var age=6;
console.log("name:"+window.name+" age:"+window.age)
})(name,age)
</script>

还可以再私有的作用域里,修改全局的属性(修改window的属性);

//这个是移动端zepto实现的原理;
var fn=function (){
function fn(){

}
return fn
}();
fn()//这个时候就可以用函数里面的fn了;
<script>
var name="china";
var age=5000;
;(function(name,age){
var name="珠峰";
var age=6;
console.log("name:"+window.name+" age:"+window.age)
})(name,age);

//这个是移动端zepto实现的原理;
var fn=function (){
function fn(){

}
return fn
}();
fn();//这个时候就可以用函数里面的fn了;
//在真实项目中,为了避免全局变量的污染,是禁止使用全局变量的;我们把要实现的功能用闭包的机制封装起来;
// 比如1、两个人都写了全局变量;
/*
function fn1(){
//A写的函数
}
function fn2(){
//B写的函数
}
* */
//上面的可以用封包来实现;封包如下;
;(function(){
function fn1(){
//A写的函数
}
function fn2(){
//B写的函数
}
})()//这个就可以封装成一个包裹了,就是自执行函数;
</script>

上面是闭包的真实应用;

下面是没有总结完的;需要看1-2-04

//jQuety原理
(function(window,undefined){
var jQuery=function(){

};
window.jQuery=window.$=jQuery;
})(window);

······

jq的原理

//jQuety原理
(function(window,undefined){
var jQuery=function(){

};
window.jQuery=window.$=jQuery;
})(window);

————————————–

第二、知识点:

<script>
function fn(){
var a=12;
console.log(a);
}
fn();
fn();
</script>

fn(),执行完以后会被销毁的;这就是前段这么火的原因;因为JavaScript做出来的东西,会被销毁,也有内存泄露(内存无法销毁的情况)052701

fn()执行后就销毁;第二次执行后还会被销毁;

下面是销毁的实例;

<script>
function fn(){
var a=12;
a++;
console.log(a);
}
fn();//13、因为执行后销毁了;
fn();//13、因为执行后销毁了;
</script>

————

QQ空间点赞效果:代码如下 :

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body,div,input{
margin: 0;
padding: 0;
font-family: cursive;
font-size: 18;
}
#conut{
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid red;
cursor: pointer;
border-radius: 15px 30px;
}
#conut span{
font-size: 14px;
color:blue;
margin-left: 5px;
}
</style>
</head>
<body>
<div id="conut">赞
(<span>0</span>)
</div>
<input type="button" id="btn1" value="赞">

<script>

var oBtn=document.getElementById("btn1");
var oDiv=document.getElementById("conut");
var oSpan=oDiv.getElementsByTagName("span")[0];

oBtn.onclick=function(){
oSpan.innerHTML=Number(oSpan.innerHTML)+1;
}
</script>
</body>
</html>

用innerText也可以

<script>

var oBtn=document.getElementById("btn1");
var oDiv=document.getElementById("conut");
var oSpan=oDiv.getElementsByTagName("span")[0];

oBtn.onclick=function(){
//oSpan.innerHTML=Number(oSpan.innerHTML)+1;//可以的
oSpan.innerText++;//也可以的;
}
</script>

可以用这种的改进的:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body,div,input{
margin: 0;
padding: 0;
font-family: cursive;
font-size: 18;
}
#conut{
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid red;
cursor: pointer;
border-radius: 15px 30px;
}
#conut span{
font-size: 14px;
color:blue;
margin-left: 5px;
}
</style>
</head>
<body>
<div id="conut">赞
<span>(0)</span>
</div>
<script>
var oDiv=document.getElementById("conut");
var oSpan=oDiv.getElementsByTagName("span")[0];

var n=0;
oDiv.onclick=function(){
n++;
oSpan.innerText="("+n+")";//也可以的;
};
</script>
</body>
</html>

可以用自定义属性来改:

<script>
var oDiv=document.getElementById("conut");
var oSpan=oDiv.getElementsByTagName("span")[0];

oDiv.name=0;//自定义属性,也避免全局污染;
oDiv.onclick=function(){
this.name+=1;
oSpan.innerText="("+this.name+")";
};
</script>

自定义属性,给元素增加一个临时属性,给一个临时的值;以后如果用到的话。我们只需要把自定义属性的值拿出来操作就可以了;

//全局自定义的不销毁;

作用域不销毁的情况:如下

<script>
function fn(){
var a=12;
return function(){
a++;
console.log(a);
};
//我们return的是一个堆内存地址;当前的这个堆内存在fn这个作用域中;
}
var f=fn();
</script>

如果一个大的函数,返回的是一个引用数据类型(经常是function),那么当前这个大的函数形成的作用域就不能销毁了,里面的私有变量也就一直存在,不销毁;图解如下函数作用域不销毁的情况

如果执行f();后会再开辟一次;直接后a变成13了,执行后,堆内存消失,但是栈内存内的a变成13了;

如果再次执行f(),会新开辟一个空间

a++;
console.log(a);

a会继续去上一层找,找到了a=13;然后++后;返回是14;

这里的a是不消失的;

//a++是把fn下的a变成++的;因为这里面没有a,是找到上一层,改变上一层里面a的值;而且上一层还不会被销毁;因为f指向这个栈内存(就是a++的上一层韩硕),f这个作用域不消失,所以a也会保存下来,但是里面小函数执行后会自动销毁;

上面的点赞效果,可以用这个思路来做;

oDiv.onclick=(function(){
var n=0;
return function f(){
n++;
oSpan.innerHTML="("+n+")"
}
})();

这个时候,即做了不销毁,又做到了n不是全局变量,不会对全局污染;

——————————-

思考题:

1、用作用域不销毁的原理,优化我们之前写过的选项卡(不能用自定义属性)。至少有2种方案

2、第1天教材的最后两道题;pag13/14/15,自己回家研究;

———–

明天总结:this:

单利模式、工厂模式、构造函数模式;

//链继承、数组高级、以后总结;

 

 

 

““““`