作用域、作用域链、闭包、call、apply、arguments.callee、caller

变量

  1. imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就位全局对象所有。
  2. 一切声明的全局变量,全是window的属性 window就是全局的域

预编译

  1. 创建AO对象 Activation Object(执行期上下文 ) (全局创建GO对象 Global Object)
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
  3. 将实参值和形参统一
  4. 在函数体里面找函数声明,值赋予函数体 (if语句中不允许出现函数声明)

函数定义的方法

  • 函数声明
    function fn(){}
  • 函数表达式
    var fn = function(){} 匿名函数表达式
    var fn = function test(){} 命名函数表达式
参数
  • 获取实参 arguments
  • 获取形参长度 函数名.length

函数的形参和arguments有映射关系但不是同一个,形参赋值,arguments里的值跟着改变,若实参为空,形参的值和arguments中对应的值没有映射关系,即使后边给arguments赋值也没有映射关系
例如:

function test(a){
	console.log(arguments[0])//1
	a=10;
	console.log(arguments[0])//10
	arguments[0]=20;
	console.log(a)//20
}
test(1)
---------------------------------------------
function demo(a,b){
	console.log(arguments[1])//undefined
	console.log(b)//undefined
	b=10;
	console.log(arguments[1])//undefined
	console.log(b)//10
	arguments[1]=20;
	console.log(arguments[1])//20
	console.log(b)//10
}
demo(1)

作用域

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

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

//作用域链详解
a defined   a.[[scope]] -- > 0 : GO

a doing     a.[[scope]] -- > 0 : aAO
							 1 : GO
 							 
b defined   b.[[scope]] -- > 0 : aAO
							 1 : GO

b doing     b.[[scope]] -- > 0 : bAO
							 1 : aAO
							 2 : GO

c defined   c.[[scope]] -- > 0 : bAO
							 1 : aAO
							 2 : GO

c doing     c.[[scope]] -- > 0 : cAO
							 1 : bAO
							 2 : aAO
							 3 : GO


闭包

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

闭包的作用
  1. 实现公有变量 eg:实现一个累加器
	function add(){
		var count = 0;
		function b(){
			count++;
			console.log(count)
		}
		return b;
	}
	var Counter = add();
	Counter()
	Counter()
	Counter()
	Counter()

  1. 可以做缓存 (存储结构)
	function eater(){
		var food = "";
		var obj = {
			eat : function () {
				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

  1. 可以实现封装,属性私有化
	function Zhang(name,wife){
		var prepareWife = 'xiaozhang';
		
		this.name = name;
		this.wife = wife;
		this.divorce = function(target){
			this.wife = prepareWife;
		}
		this.changePrepareWife = function (target){
			prepareWife = target;
		}
		this.sayPraprewife = function () {
			console.log(prepareWife);
		}
	}
	var zhang = new Zhang('zhang','xiaoliu');

	//只有自己能看到或者设置了向外展示的方法
	console.log(zhang.prepareWife) //undefined
	console.log(zhang.sayPraprewife())//xiaozhang
	
  1. 模块化开发,防止污染全局变量
	var name = 'abc';
	var init = (function () {
		var name = 'aaa';

		function callName() {
			console.log(name)
		}

		return function (){
			callName();
		}
	}())
	console.log(init())//aaa 

立即执行函数 - 针对初始化功能的函数

此类函数没有声明,在一次执行过后即释放,适合做初始化工作
只有表达式才能被执行符号执行

	function test(a,b,c,d){
		console.log(a,b,c,d);
	}(1,2,3,4)
//被解析成↓↓↓两部分(能不报错就不报错原则)
	function test(a,b,c,d){
		console.log(a,b,c,d)
	}


	(1,2,3,4)

//不报错

call 和 apply、bind

  • 作用:改变this指向
  • 区别:传参列表不同
    • call 需要把实参按照形参的个数传进去
    • apply 需要传一个arguments(数组形式的实参列表)
    • bind 传参和call一致,返回一个函数需再次执行
	//Person() => Person.call() 两者等价
	//Person([1,2,3]) => Person.apply(null,[1,2,3]) 等价
	//Person.call(obj,xxx,xxx)
	//Person.bind(obj,xxx,xxx)()
	//第一个参数:this指的方向
	//第二、三...个参数:传进Person的实参、
	
	
	function Person(name,age){
		this.name = name;
		this.age = age;
	}
	var person = new Person('deng',100);

	//1.
	var obj = {};
	Person.call(obj, 'cheng', 300)
	console.log(obj)//{name:'cheng',age:300}

	//2.
	function Student(name,age,sex,tel,grade){
		Person.call(this,name,age);
		this.sex=sex;
		this.tel=tel;
		this.grade=grade;
	}
	var student = new Student("sunny",123,'male',152,2017)
arguments.callee
	//arguments.callee指向函数引用(函数自身)
	var num = (function(n){
    if(n==1){
        return 1;
    }
	return n*arguments.callee(n-1)
}(10))
caller
	//调用该函数的环境
	function test(){
		demo()
	}
	function demo(){
		console.log(demo.caller)// test函数
	}
	test()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值