看完视频后,https://www.bilibili.com/video/BV167411v7bB?p=1 的总结。
this的指向:
1.默认绑定, 分别对应函数的四种调用: ----独立调用
2.隐式绑定, ----方法调用
3.显示绑定, ----间接调用
4.new绑定, ----构造函数调用
5.严格模式下this的指向
6.隐式丢失。(*—*)
1.默认绑定(本质都是独立调用嘛)----- 独立调用(this指向window)
1> 全局环境下,this指向的window
<script type="text/javascript"> console.log(this) //window </script>
2 > 函数被独立调用时,内部的this指向window
<script type="text/javascript"> function fn(){ console.log(this); } fn(); //window </script>
3> 被嵌套的函数在独立调用的时候,this指向的是window
<script type="text/javascript"> var a = 100; var obj = { a : 0 , hello : function(){ function fine(){ console.log(this.a) } fine() //独立调用 } } obj.hello() //100 </script>
4> 自执行,被嵌套的自执行,函数中的this指向window
<script type="text/javascript"> (function (){ console.log(this); })() //window var b=100; function hello(){ var b =10; (function fine(){ //自执行嵌套进函数内部 console.log(this.b); //100 })() } hello(); </script>
5> 闭包函数的this指向window
<script type="text/javascript"> var k=100; var obj = { k :0, hello : function(){ function fine(){ console.log(this); //window return k ; //100 } return fine() } } console.log( obj.hello()); </script>
2.隐式绑定 ---- 方法调用(看调用this的对象直接指向了谁,那么this就直接指向了谁)
1> 作为对象的方法被调用时,指向的是对象
<script type="text/javascript">
var a = 100;
function hello(){
console.log(this.a);
}
var obj = {
a :0,
fine:hello,
}
obj.fine(); //0
</script>
具体看清楚到底是谁在调用
<script type="text/javascript"> var a = 100; function hello(){ console.log(this.a); } var obj = { a :0, fine:hello, obj2:{ a:200, fine:hello } } obj.fine(); //0 obj.obj2.fine(); //200 </script>
3.显示绑定 ------ 间接调用
1> 通过call() , apply(), bind() 把对象绑定到this上
<script type="text/javascript"> var a = 100; function hello(){ console.log(this.a) } var obj ={ a:0 } hello(); //100 hello.call(obj); //0 hello.apply(obj); //0 var fn = hello.bind(obj); fn(); //0 </script>
2> 硬绑定 ,this不能再被改变了
<script type="text/javascript"> var a = 100; function hello(){ console.log(this.a) } var obj ={ a:0 } var bar = function(){ hello.call(obj) //硬绑定到obj } bar(); // 0 bar.call(window); //0 ,不会被改变 </script>
看懂了上面,再来看 call() , apply(), bind() 的具体用法:https://www.runoob.com/w3cnote/js-call-apply-bind.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
apply()一个很强大的功能——能将一个数组默认转化为参数列表!!!
再来思考一下:
https://www.nowcoder.com/questionTerminal/d47b482e7148497582c7a995df51f393?f=discussion
其中:Array.prototype.slice():
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
3> js中很多内置函数也有显示绑定的作用
4.new绑定 -------构造函数调用
1> new实例化
<script type="text/javascript"> function fn(){ console.log(this); } fn(); //window var mynew = new fn(); console.log(mynew); //fn , 用new来执行函数,this指向的是当前实例化的对象即fn </script>
<script type="text/javascript"> var person = { fav : function (){return this;} } console.log(person.fav()); //打印的是person对象 var p = new person.fav(); console.log(p);//打印的是fav对象,因为实例化的是fav,this指向实例化的对象 </script>
2> return的对象也是实例化的对象
5.严格模式下this的指向
1> 严格模式下,独立调用的函数内部的this指向了undefined。
2> 严格模式下,函数apply() 和 call()内部的this始终指向它们的第一个参数。
6.隐式丢失 *—*
被隐式绑定的函数丢失了绑定对象后,this默认绑定到window
1> 函数别名
<script type="text/javascript"> var a = 100; function fine(){ console.log(this.a); } var obj = { a:0, hello:fine } obj.hello(); //0 var bar =obj.hello; // bar被赋值为obj.hello。bar和obj毫无关系,this隐式丢失 bar(); //100 ,隐式丢失,默认this指向的是window </script>
2> 参数传递
<script type="text/javascript"> var a = 100; function hello(){ console.log(this.a); } function bar (fn){ fn(); } var obj = { a:0, fine:hello } obj.fine(); //0 , 是一个对象的方法 bar(obj.fine);//100 把obj.fine作为参数传递,obj和bar毫无关系,this丢失了它的绑定对象,指向window </script>
3> 内置函数
( setTimeout() 和 setInterval() 等函数,它们的第一个参数的回调函数中的this默认指向的是window )
<script type="text/javascript"> var a =100; function hello(){ console.log(this.a); } var obj = { a:0, fine:hello } setTimeout(obj.fine,1000); //100 </script>
4> 间接调用
<script type="text/javascript"> var a =100; function hello(){ console.log(this.a); } var obj = { a:0, fine:hello } var p ={a:7}; obj.fine(); //0 (p.fine = obj.fine) (); // 100 立即执行,obj.fine赋值给了p的fine函数,立即执行,this指向了window. p.fine(); //7 , 间接调用,this指向的是调用它的对象 </script>
总原则:在非严格模式下,如果函数没有通过构造函数调用,直接作为普通函数使用,this指向window,在严格模式下,this指向undefined。
改变this的指向:
1>隐式绑定,调用this的对象直接指向了谁,this就指向谁。
2>显示绑定,apply,call,bind.
3>new实例化对象,this指向的是当前实例化的对象。