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>
原文地址:https://www.cnblogs.com/hellowzd/p/13891317.html