<强>一,其实可以类比成人强>
说到这的话,我们在js中主要研究的都是函数中的这一点,在javascript中,这代表当前行为的执行主体,而上下文代表的是当前行为执行的的环境(区)域。
例如男神在北理珠吃饭,这句话分别代表的含义如下
,男神——祝辞的在主体(这)
,吃饭,祝辞的在函数(函数)
北理珠——在祝辞环境(上下文)
,——祝辞的在说明:吃饭是函数,男神是函数的主体,北理珠就是当前行为的执行环境(上下文),主体跟上下文没有必然的联系,主体只与函数有关系,就好像男神吃饭,其实哪里都可以吃饭,吃饭这个动作的主体永远都是男神,环境是可以变化的。
——在祝辞结论:上面,其实也可以说明,这指的是谁,和函数在哪里定义和执行是没有任何关系的。
<强>二,在函数中,如何区分这强>
1,函数执行,首先看函数名前面是否有”。”,有的话,“。”前面是谁,这就是谁,没有的这就话是窗口
//例子一 console.log(这个); 函数吃(){ console.log(这个);//这个→窗口 } ~函数(){ 吃();//这个→窗口 }();//例子二 函数fn () { console.log(这个); } var obj={fn: fn}; fn ();//这个→窗口 obj.fn()//这个→obj//例子三 函数sum () { fn (); } sum ();//这个→窗口//例子四 var oo={ 总结:函数(){ console.log(这个); fn (); } } oo.sum ();//首先求和函数里面,第一个输出这为oo,之后执行fn(),这为窗口
2,立即执行函数中这样的永远都是窗口
(函数(){ console.log(这个);//这个→窗口 })()
3,给元素的某一事件绑定方法,当事件触发的时候,执行对应的方法,方法中的这是当前元素
函数fn () { console.log(这个); }//例子一 . getelementbyid (“div1”)。onclick=fn;//这个→dom元素//例子二 . getelementbyid (“div1”)。onclick=function () { console.log(这个);//这个→# div fn ();//这个→窗口 }
结论:找到函数在哪里执行的,有点,这就是点前面东西,没点,这就是窗口
<强>三、使用这个分析一道面试题强>
var num=20; var obj={ num: 30, fn:函数(num) { 这一点。num *=3; num +=15; var num=45; 返回函数(){ 这一点。num *=4; num +=20; console.log (num); } })(num) }; var fn=obj.fn; fn ();//?5 obj.fn ();//?5 console.log(窗口。num obj.num)//?40、120
上面代码使用堆栈图来描述,如下,首先正方形代表栈内存(函数执行环境,上下文),圆边方形代表堆内存(用来存放字符串)。
第一步,形成一个js执行环境,窗口作用域,首先预解释(声明var,声明+定义功能),
第二步,代码由上往下执行,num=20, obj=引用数据类型(数据存在堆内存里面)
第三步,因为obj.fn是立即执行函数,所以形成一个私有作用域,执行fn里面的函数,因为fn里面的函数返回值为函数,返回值被外面的obj.fn引用了,这个立即执行函数的作用域不销毁。
第四步,窗口作用域下面的代码继续往下执行。
<强>四,这实践运用强>
现在有这样一个需求,要求做一个累加器,每点击一次,就累加1 .
var oBtn=. getelementbyid (btn); var spanNum=. getelementbyid (“spanNum”);//方法一//利用全局作用域不销毁的原理,把需要累加的数字定义为全局变量 var计算=0; oBtn。onclikc=function () { 数+ +; spanNuM。innerText=实现计数; }//弊端:在项目中为了防止全局变量之间的冲突,我们一般是禁止或者减少使用全局变量的//方法二//形成一个不销毁的私有作用域保存我们需要累积的数据//1) (函数(){ var计算=0; oBtn。onclick=function () { + +计数; spanNum。innerText=实现计数; } })//2) oBtn。onclick=(函数(){ var计算=0; 返回函数(){ + +计数; spanNum。innerText=实现计数; } })//上面的两种写法都是表达同一个意思//弊端:有一个不销毁的私有作用域,占那么一点点内存//方法三//利用innerHTML的方式处理,每点击一次都需要到页面获取最新的值,然后累加,最后把结果放进去 oBtn。onclick=function () { + + spanNum.innerHTML; }//弊端:innerHTML获取的时候本来就需要浏览器去处理,每一次都需要把页面的内存先转化为字符串,然后累加,累加完重新添加回去,当重新添加的时候浏览器需要重现渲染一遍页面。//方法四//利用自定义属性存储(推荐!) oBtn。数=0; oBtn。onclick=function () { spanNum。innerTxt=+ + this.count; }//注意,这里的只数是对象的一个属性,它既不是全局变量,也不是局部变量哦。这在JavaScript函数中的指向及实例详解