js补充作用域

作用域


每一个对象都有属性和方法
[[scope]]:每个js函数都有一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供js引擎存取[[scope]]就是其中一个。
[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。

作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行期上下文,当函数执行完毕,它所有的执行期上下文被销毁。
查找变量:从作用域链的顶端一次向下查找。
在哪个函数查找就在哪个函数的顶端向下查找

function a(){
	function b(){
		var b = 234;
	}
	var a = 123;
	b();
}
var glob = 100;
a();

a创建的时候[[scope]]中有一个GO 0
a执行的时候[[scope]]产生AO 0 GO 1向下移
b创建的时候直接拥有a的劳动成果
b执行的时候产生一个AO 所以在b里面访问变量的时候先访问b在放我那 AO 0 AO 1 GO 2

function a(){
	function b(){
		function c(){
			
		}
		c();
	}
	b();
}
a();

a definded a.[[scope]] 0 :GO

a doing    a.[[scope]] 0 :AO
                       1 :GO
                       
b definded b.[[scope]] 0 :AO  a
                       1 :GO
                       
b doing    b.[[scope]] 0 :AO  b
                       1 :AO  a
                       2 :GO 
                       
c definded c.[[scope]] 0 :AO  b
                       1 :AO  a
                       2 :GO 
                       
c doing    c.[[scope]] 0 :AO  c
                       1 :AO  b
                       2 :AO  a
                       3 :GO     

闭包

function a(){
	function b(){
		var bbb = 234;
		document.write(aaa);
	}
	
	var aaa = 123;
	return b;
}			
var glob = 100;
var demo = a();
demo();		   

内部的函数保存到外部必须生成闭包
function a(){
	var num = 100;
	function b(){
		num++;
		console.log(num);
	}
	return b;
}

var demo = a();
demo(); //101
demo(); //102

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。

闭包的作用
1.实现公有变量
 

	function add(){
		var count = 0;
		function demo(){
			count ++;
			console.log(count);
		}
		return demo;
	}
	var counter = add();
	counter();
	counter();
	//累加器
	
	function test(){
		var num = 100;
		function a(){
			num++;
			console.log(num);
		}
		function b(){
			num--;
			console.log(num);
		}
		return [a,b];
	}
	var myArr = test();
	myArr[0]();//101
	myArr[1]();//100
//不依赖外部变量的累加器
	function test(){
		var num = 0;
		function add(){
			console.log(++num);
		}
		return add;
	}
	var myAdd = test();
	test()//---1
	test()//---2

2.可以做缓存(存储结构)

    function eater(){
        var food = "";
        var obj = {
            eat:funvtion(){
                console.log("i am eating"+food);
                food = "";
            },
            push:function(myfood){
                food = myFood;
            }
        }
        return obj;
    }
    var eater1 = eater();
    eater1.push("banana");
    eater1.eat(); //i am eating banana


3.可以实现封装,属性私有化。

4.模块化开发,防止污染全局变量

立即执行函数

定义:此类型函数没有声明,在一次执行过后即释放。适合做初始化工作。

//立即执行函数
//针对初始化功能的函数
(function (){
	var a = 123;
	var b = 234;
	console.log(a+b);
}());

(function (a,b,c){

	console.log(a+b+c);
}(1,2,3));

var num = (function (a,b,c){

	return a+b+c;
}(1,2,3));



(function (){}());  w3c建议第一种
(function (){})();

//只有表达式才能被执行符号执行

//函数声明  不是表达式所以不能被执行
function test(){
	var a=123;
}

//函数表达式 能执行
var test = function (){
	console.log(123);
}();
//一个表达式被执行忽略函数名

function test(a,b,c,d){
	console.log(a+b+c+d);
}(1,2,3,4);//不会执行也不会报错 

function test(){
	var arr = [];
	for(var i = 0;i<10;i++){
		arr[i] = function(){
			document.write(i+"");
			//在执行的时候才会执行这一句
			//在执行的时候i已经变成10
		}
	}
	return  arr;
}
var myArr = test();
for(var j = 0;j<10;j++){
	myArr[j]();
}

//10 10 10 10 10 10 10 10 10


//若想输出0,1,2,3.....
function test(){
	var arr = [];
	for(var i = 0;i<10;i++){
		(function(j){
			arr[j] = function(){
				document.write(j+"");
			};
		}(i));
	}
	return  arr;
}
var myArr = test();
for(var j = 0;j<10;j++){
	myArr[j]();
}
//0 1 2 3 4 5 6 7 8 9
//计算字符串的长度

function reByteslen(target){
	var count = 0;
	for(var i = 0;i<target.length;i++){
		if(target.charCodeAt(i)<=255){
			count++;
		}else if(target.charCodeAt(i)>255){
			count +=2;
		}
	}
	console.log(count);
	
}


//简化
function reByteslen(target){
	var count,
	    len;
		count = len  = target.length;
	for(var i = 0;i<len;i++){
	if(target.charCodeAt(i)>255){
			count ++;
		}
	}
	console.log(count);
}
var f = (
	function f(){ 
		return "1";
	},
	function g(){
		return 2;
	}
)();

typeof f;//number

var x = 1;
if(function f(){}){
	x+=typeof f;
}
console.log(x);//1undefined

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值