这的定义
表示当前执行代码的环境对象
,因此可将这的剖析分为“全局环境”和“函数环境”两种类型的环境对象
全局环境
控制台。日志(这个===窗口);//正确的 var=10; console.log (this.a);//10
函数环境
在函数内部,这的取值取决于函数被调用时的运行环境。
这里涉及到内存里的数据结构相关的知识点,当我们定义以下字面量对象时会发生一系列的关联关系
var obj={名称:‘汤姆’};
javascript引擎会先在内存中生成{名称:‘汤姆’,}对象,接着再把这个对象的内存地址赋值给obj变量,所以,obj变量保存的只是一个内存地址而已,如果要获取obj.name, javascript引擎会先从obj变量中拿到内存地址,然后从该地址中获取原始对象,再返回名字属性。
而属性值为函数时,该函数会被保存在内存中,然后将该内存地址赋值给该属性,因此该地址赋值给不同环境执行时它的作用域是不一样的,而这对象就是指向函数当前的执行环境对象,执行环境是会在事件循环(事件循环)过程中变化的,因这个在此函数环境下是属于运行时的。
var=疤滥贰泵? var obj={ 名称:“冰山”, 说:函数(){ 控制台。日志('我的名字是' + this.name); }, 子:{ 说:函数(){ 控制台。日志('我的名字是' + this.name); } } }; obj.say ();//我的名字是冰山一角 obj.sub.say()//我的名字是定义; var说=obj.say; 说();//我的名字是汤姆。 >之前上面的例子说明obj.say()执行环境为obj对象,而obj.sub.say()的执行环境却是obj。子对象,而对于obj。子来说并没有名字属性,因此为未定义;而var说=obj.say;则表示将说方法的内存地址赋值给全局变量,因此从全局变量名字中取值。
运用场景
接下来从这在函数环境下的不同运用场景来剖析
事件回调函数
={var处理程序 绰号:“匿名”, 注册:函数(){ console.log (this.nickname); } } $ (" # registerBtn”)。(“点击”,handler.register);//定义 >之前以上逻辑点击触发后输出的是未定义的,因为函数被当做事件触发的回调函数执行时,这是指向该触发事件对应的元素,如要这仍然以处理程序对象为执行环境,则可使用函数的结合方法进行执行环境对象的绑定操作。
$ (" # registerBtn”)。(“点击”,handler.register.bind(处理器));//匿名在反应中经常需要在回调函数中调用this.state,。道具,按照上面的分析,将当前环境对象绑定到回调函数中即可。
如果是使用的箭头函数定义回调函数即可无需绑定,因为箭头函数中这就是对应定义时所在的对象。
,构造函数要理解这在构造函数中的逻辑就要理清楚构造函数在实例化过程中都发生了什么。
函数(){ this.name=滥贰? 这一点。=20岁; } var=new (),使用新命令实例化构造函数一的过程中会发生以下流程
<李>创建一个空对象,作为将要返回的对象实例李> <李>将该空对象的原型指向构造函数的原型属性李> <李>将该空对象赋值给构造函数内部的这关键字李> <李>执行构造函数内部代码李> <李>默认返回这对象(如,回报的为非对象类型,如数123字,会被忽略进而默认返回这对象)李> <李>由以上逻辑可知道这关键字在构造函数中表示的是其实例对象。李>
绑定
绑定方法将函数体中这个指的向新对象并返回一个新函数
函数(){ 这一点。昵称=滥贰? 这一点。说=function () { console.log (this.nickname); } } var b={昵称:“约翰”}; var=new (); var说=a.say; var say1=a.say.bind(一个); var say2=a.say.bind (b); 说();//定义 say1 ();//汤姆 say2 ();//约翰 >之前调用,应用
调用方法是指Function.prototype。电话,因此每个函数都会具备调用方法,有趣。调用(thisArg __arg1,最长,…),调用方法接收的第一个参数会替换原有这个指的向的执行环境对象。
javascript的这关键字详解