这是当前函数/模块的运行环境上下文。它是一个指针变量,普通函数中的this在调用时通过绑定确认指向。使用不同的this调用相同的函数会产生不同的结果。您究竟如何知道这是必然的?本次绑定的规则1.默认绑定函数a(){}a();独立调用函数时,没有没有任何修饰的函数引用。在非严格模式下,this指向全局对象vara='hello';varobj={a:'world',foo:function(){console.log(this.a);},};让bar=obj.foo;bar();//调用的时候直接调用hello。所以它指向了全局的this//obj.foo();//world在严格模式下,this指向undefined。在严格模式下,不允许指向全局对象。vara='hello';varobj={a:'world',foo:function(){'usestrict';控制台日志(this.a);},};让bar=obj.foo;bar();//会报错,因为this指向一个未定义的普通函数作为参数传递,setTimeOut,setInterval,非严格模式下this指向全局对象。varname='hello';varperson={name:'world',sayHi:sayHi,};functionsayHi(){console.log(this);//personsetTimeout(function(){//指向全局对象console.log(this.name);//hello});}person.sayHi();2.隐式绑定与默认绑定相反。函数调用时有显式修改,vara='hello';varobj={a:'world',foo:function(){console.log(this.a);},};//谁调用这个函数(foo)就是这个函数的thisobj.foo();在链式调用的情况下,this指向最近的函数sayHi(){console.log(this.name);}varperson1={name:'hello',sayHi:sayHi,};varperson2={name:'world',friend:person1,};//链式调用时指向person2.friend.sayHi();显式绑定调用applybind可以修改函数的this点。call和apply的异同是改变this点,然后将原函数的第一个参数执行为this,绑定到函数体的this上。如果没有给fun.cal()传递参数,在非严格模式下,this会绑定到全局对象func.call(this,arg1,arg2,...,argn);func.apply(this,[arg1,...,argn])//只有对象tostring可以返回类型Object.prototype.toString.call(obj)==='[objectArray]'如果调用的第一个参数传递一个基本类型会发生什么例如数字或字符串?获取字符串对象,数字对象[Number:1][String:'lubai']和其他bindbind方法将创建一个新函数。当这个新函数被调用时,bind的第一个参数会作为函数运行时的this,后面会传入一系列的参数作为它的函数,然后再传递实参。varaccount={name:'hello',author:'world',subscribe:function(subsc){console.log(`${subsc}${this.name}`);},};account.subscribe('微言');//微言hellovarsubsc1=account.subscribe.bind({name:'name',author:'author'},'subsc');subsc1();//subscname(显式绑定的优先级高于隐式绑定)new创建一个空对象,将空对象的\_\_proto\_\_指向原型对象的prototype到new对象就是这个执行原始构造函数returnfunctionStudy(name){this.name=name;}varstudy=newStudy('hello');console.log(study.name);5.这个绑定级别的优先级newbinding>explicit(bind,call,apply)binding>implicitbinding(obj.foo())>defaultbinding(foo())//显式绑定的优先级,比隐式绑定高functionfoo(a){//console.log(this.a);this.a=a;}varobj1={a:2,foo:foo,};varobj2={a:3,foo:foo,};//隐式绑定obj1.foo();//2obj2.foo();//3//强行改变这个obj1.foo.call(obj2)的点;//3obj2。foo.call(obj1);//2functionfoo(a){//console.log(这个.a);this.a=a;}varobj1={foo:foo,};varobj2={};obj1.foo(2);console.log(obj1.a);//2//强制将foo的参数指向obj2obj1.foo.call(obj2,3);console.log(obj2.a);//3//new指向obj1到bar,相当于bar.a=a,不会改变对象obj1varbar=newobj1.foo(4);console.log(obj1.a);//2console.log(bar.a);//4functionfoo(a){this.a=a;}varobj1={};//bind执行的this变为obj1varbar=foo.bind(obj1);bar(2);console.log(obj1.a);//2varbarNew=newbar(3);//在new的过程中,以new对象为thisfunction运行原构造函数foo(a){this.a=a}//new对象为barNewconsole.log(obj1.a);//2console.log(barNew.a);//3箭头函数箭头函数没有参数箭头函数没有构造函数(本身没有构造函数)也没有this(this的指向由箭头函数定义的位置决定,而普通函数是在调用时确定的)主题练习主题1vara=123;functiongetA(){console.log(this.a)//undefined}getA()vara=123;varobj={a:456,getA:function(){//console.log(this)这里this指向objfunctiongetAA(){//有一个独立的thisconsole.log(this.a)//undefined}getAA()//默认绑定}}obj.getA()//未定义主题2varlength=10;functionfn(){console.log(this.length)}varobj={length:5,method:function(fn){//this=obj//fn为参数,this以函数为参数指向全局fn();10//arguments{0:fn,1:1,length:2}等同于绑定到fn对象的隐式绑定arguments[0]()}}obj.方法(fn,1)
