js 闭包 作用域
一般规律:就近原则,向上取变量
闭包:通过引用把函数放入内存,此函数依赖的作用域不会被立即释放,因为内存中的函数需要随时被调用,这放到任何语言中应该都适用
回调:有时需要封装一个过程,当别人调用时可以灵活的展现出不同的自定义结果
箭头函数作用域:箭头的作用域在上一级
<script>
var a = "123";
//正常函数 向上取变量
function b(){
console.log(a);
}
b();
//正常函数 就近原则
function c(){
var a = "456";
console.log(a);
}
c();
//正常函数 向上重写变量
function c1(){
a = "asd";
console.log("c11---->",a);
}
c1();
console.log("c12---->",a)
//函数嵌套
function d(){
function e(){
var f = "111";
console.log("f------>",f);
}
e();
}
d();
//函数嵌套 内层函数对上部变量重写
function g(){
var as = "as";
function h(){
console.log(as);//内不函数能向上取到变量
console.log("3------------->",a);
a = "222";
console.log("4------------->变量重写后",a);
}
console.log("2------------->",a);
h();
console.log("5------------->",a);
}
console.log("1------------->",a);
g();
console.log("6------------->",a);
//函数嵌套
function g1(){
a = "ar";//正常函数 向上重写变量
function h(){
console.log(a);//正常函数 向上取变量
}
h();
}
g1();
//定义一个匿名函数 立即执行
var h = function(){
console.log("h---------------->",a);
}();
console.log("h--------------->",h);
//定义一个匿名函数 调用执行
var h1 = function(){
console.log("h1---------------->",a);
};
h1();
console.log("h1--------------->",h1);
//函数返回值
function s(){
var x = 1;
return x;
}
var s1 = s();
console.log("s1---->",s1)
//一个函数能否取到另一个函数定义的值
//function s2(){
//console.log("x---->",x);
//}
//s2();
// 比较--------------------------------------------------
//正常嵌套1
function a1(){
var i = 0;
function c1(){
i++;
console.log("i---->向上取值,取上个函数作用域的值",i)
}
c1();
}
a1();
a1();
var b = a1();
console.log(b);
//变形1并与改写3对比
function a1s1(){
var i = 0;
function c1(){
i++;
console.log("iss---->变形1并与改写3对比",i)
}
return c1();
}
a1s1();
a1s1();
//变形2并与改写3对比
function a1s33(){
var i = 0;
function c1(){
i++;
console.log("iss---->变形2并与改写3对比",i)
}
return c1;
}
a1s33()();
a1s33()();
//变形3并与改写3对比----------自增了
function a1s22(){
var i = 0;
function c1(){
i++;
console.log("iss---->变形3并与改写3对比",i)
}
return c1;
}
var sss = a1s22();//通过引用把函数放入内存,此函数依赖的作用域不会被立即释放,因为内存中的函数需要随时被调用,这放到任何语言中应该都适用
sss();
sss();
//变形4思考
function a1s223(){
function c1(){
var i = 0
i++;
console.log("iss---->变形4思考",i)
}
return c1;
}
var sss1 = a1s223();
sss1();
sss1();
a = 0;
//变形5思考
function a1s2235(){
function c15(){
a++;
console.log("iss---->变形5思考",a)
}
return c15;
}
var sss15 = a1s2235();
sss15();
sss15();
//改写3
function asv() {
var counter = 0;
var s = function f() {
counter++;
console.log("改写3---->",counter)
}
return s;
};
var asv1 = asv();
asv1();
asv1();
asv1();
// 比较--------------------------------------------------
//一个例子
var add = (function () {
var counter = 0;
return function () {
console.log(counter)
return counter += 1;
}
})();
add();
add();
add();
//改写1
function ass() {
var counter = 0;
return function () {
console.log("改写1---->",counter)
return counter += 1;
}
};
var ass1 = ass();
ass1();
ass1();
ass1();
//改写2
function asg() {
var counter = 0;
return function () {
counter++;
console.log("改写2---->",counter)
return counter;
}
};
var asg1 = asg();
asg1();
asg1();
asg1();
console.log("a----------------------->",a);
a = 9;
//正常嵌套2
function sc2(){
function scs(){
a++;
console.log("scs---->向上取值,取上上个函数作用域的值",a)
}
scs();
}
sc2();
sc2();
//正常嵌套3
function sc3(){
function scs1(){
function scs2(){
a++;
console.log("scs---->向上取值,取上上个函数作用域的值",a)
}
scs2();
}
scs1();
}
sc3();
sc3();
//抽象
a = 0;
a++;
console.log("a1-------->",a);
a++;
console.log("a2-------->",a);
//函数返回一个匿名函数
function ss(){
a = 0
console.log("a001---->",a);
return function(){//定义一个匿名函数 未立即执行
a++;
console.log("x001---->",a);
};
console.log("x002---->",a);//return之后不执行
}
var ss1 = ss();
console.log("ss1---->",ss1)
var ss10 = ss();
var ss11 = ss();
var ss12 = ss();
var ss13 = ss();
var ss2 = ss();
ss2();//这里变量a自增了
ss2();//这里变量a自增了
ss2();//这里变量a自增了
//函数返回一个具体的值
function as(){
a = 3;
function as1(){
a++;
}
as1();
console.log(a);
return a;
}
var bs = as();
console.log("bs---->",bs);
//bs();
//bs();
//bs();
console.log("--------------------------------")
//函数返回一个正常的函数
function ab(){
a = 100;
var ff = function ab1(){//定义一个变量,这个变量是一个函数
a++;
console.log("ab------------->",a)
}
console.log("abs------------->",a);//这里abs之被执行了一次
return ff;
}
var cc = ab();//cc = ab1这个函数
cc();//这里变量a自增了
cc();//这里变量a自增了
cc();//这里变量a自增了
console.log("cc-------------->",cc);
//变形1
var asf = function sc(){
a++;
console.log("asf----->"+a);
}
//console.log(asf);
asf();//这里变量a自增了
asf();//这里变量a自增了
asf();//这里变量a自增了
//变形2
var hh = 0;
function sc1(){
hh++;
console.log("sc1----->"+hh);
}
//console.log(asf);
sc1();//这里变量a自增了
sc1();//这里变量a自增了
sc1();//这里变量a自增了
//外部函数取内部函数的值
function out(){
var af = function inner(){
return 1;
}
var c = af() + 1;
console.log("c--拿到函数内部的值并进行了一次加法运算--->",c);
return af;
}
var oa = out();
console.log(oa);
var oa1 = oa();
console.log("oa1---------------->",oa1);
//调用函数内的函数
//function f1(){
// add = function(){
// console.log("1111111111111");
// }
//}
//add();
//调用函数内的函数
function f1(){
add = function(){
console.log("1111111111111");
}
}
var fn = f1();
add();
//调用函数内的函数
function fs(){
var a = 0 ;
ad = function(){
a++
console.log("ad---->",a)//1
}
bd = function(){
a++
console.log("bd--->",a)//2
}
console.log("a0-------------->",a);
}
var fss = fs();
ad();
bd();
var fss = fs();
ad();
bd();
//变形前
var a = 1
var b = function(){
return 1+a
}
console.log("1+a---->",b())
//变形后
var a = 1
var b = 1 + a;
console.log("1+a---->",b)
//------------------------------------------------------
//回调
function execute(func){
var value = {
name:'hi js'
}
func(value);
}
//测试1 有时需要封装一个过程,当别人调用时可以灵活的展现出不同的自定义结果
function say(value){
alert(value.name);
}
execute(say);
//测试2
function say1(value){
console.log(value.name);
}
execute(say1);
//------------------------------------------------
// 全局
name = 'zhangsan'
const asss = {
name: 'lisi',
sayName () {
console.log(this.name)
}
}
const bsss = {
name: 'wangwu',
sayName: () => {
console.log(this.name)//箭头的作用域在上一级
}
}
asss.sayName() // lisi
bsss.sayName() // zhangsan
</script>