美文网首页
this专题

this专题

作者: 扶不起的蝌蚪 | 来源:发表于2020-08-16 01:35 被阅读0次

this的情况一共分为5种

  • 默认绑定:在严格模式下绑定是undefined,否则绑定到全局对象window
  • 上下文调用,绑定到上下文对象(谁调用,this就是谁)
  • call/apply/bind调用,绑定到指定的对象
  • new调用,绑定到new的对象
  • DOM事件绑定,this就是绑定的哪个DOM对象

本文不讨论严格模式
本文不讨论严格模式
本文不讨论严格模式

1.默认绑定

function foo(){
    console.log(this.a);
}
var a = 2
foo() // 2
function foo(){  
    this.a = 3
    console.log(this.a);  //this->window  this.a = window.a 
}
foo()  // 3
var a = 2
function foo(){
    this.a = 4  //window.a = 4
    var b = 5
    console.log(this); //window
    console.log(this.a); //4
    console.log(this.b);//undefined
    console.log(b); //5  这个就和作用域相关和this无关了
    bar()  //这里要注意的是虽然在foo里面调用了bar,但是bar前面没有点,所以bar的this仍是window,
          //foo里面的var声明的变量b跟this一毛钱关系也没
}
foo() 
function bar(){
        console.log(this);  //window
        console.log(b)  // Uncaught ReferenceError: b is not defined
                                //注意函数的作用域链是在声明的时候确定的
                                //这里是在全局声明的函数,所以找不到a这个变量从而产生了报错
}

2.上下文调用绑定

最基本的调用绑定

var a = 20
var obj = {
    a:2,
    foo:function(){
        console.log(this.a);
    }
}
console.log(obj.foo());

地址引用绑定

var a = 20
var obj = {
    a:2,
    foo:function(){
        console.log(this.a);
    }
}
obj.foo()  //2
var bar = obj.foo
bar()   //20
这里需要注意的是bar = obj.foo实际上是bar引用的foo的堆内存地址。
bar()前面没有点,那么他的this就是window,所以这里打印出来的是20而不是2
var a = 20
function foo(){
    var a = 4
    return {
        a:100,
        bar:function(){
            console.log(this.a);
            console.log(a);
        }
    }
}
var zpt = foo()  
var ngx = zpt.bar  
zpt.bar() //100  4
ngx()   //20  4
---------------------------
这里呢zpt等于foo函数执行返回的对象,那么
zpt = {
    a:100,
    bar:function(){
        console.log(this.a);
        console.log(a);
}
zpt.bat()  看到bar前面有点,那么this就是zpt  
所以第一个a是100  第二个a是foo作用域中的a,那么就是4

对于ngx = zpt.bar    ngx是引用的bar函数的声明地址  
ngx()的时候前面没有点  那么他的this就是winodw
那么第一个打印的就是window的a,也就是20,第二个a是bar声明的时候进行作用域查找,在foo作用域找到了,那么第二个a仍然是4


一定要区分this和作用域的区别
作用域在声明的时候确定
this在执行的时候确定

3.new绑定

谁new了他,那么this就是谁,这个没啥好讲的

name = 100
function Person (name) {
  this.name = 1
}
Person.prototype.talk = function () {
  console.log(this.name)
}
var bar = new Person()
bar.talk()   // 1

4.call/bind/apply绑定

var a = 20
var obj = {
    a:2,
    foo:function(){
        console.log(this.a);
        setTimeout(function(){
            console.log(this.a);
        },1000)
    }
}
obj.foo()   // 2  20
为什么foo的第二个a是20呢 
是因为settimeout里面的匿名函数是在1秒后执行的,
但是执行这个函数的时候,前面没有点啊!!!那么他的this就是window了

如果我们在后面bind(this)

var a = 20
var obj = {
    a:2,
    foo:function(){
        console.log(this.a);
        setTimeout(function(){
            console.log(this.a);
        }.bind(this),1000)
    }
}
obj.foo()   // 2  2
那么就是正常的了

除开DOM绑定,所有的回调函数执行的时候,只要前面没有点,他们的this永远是window


    var data1 = "def";
    function func2(callBack) {
            callBack()
    }

    vice = {
        "data1" : "abc"
    };

    vice.trans = function () {
        alert(this.data1);
    };
    vice.func1 = function (callBack) {
        func2(callBack);
    };

vice.func1(vice.trans);  //def    this变成了window
你把vice.trans实际上就是函数声明时候的堆内存地址  
callBack()执行的时候前面没有点,那么不好意思,this就是window

5.DOM绑定

DOM的事件绑定有3种情况

  • 直接在直接在html标签中绑定this永远是window
<button id="btn" type="button" onclick="showThis()">点击</button>
function showThis(){
    console.log(this);
}

可以看到this指向的是window

<button id="btn" type="button" onclick="showThis(this)">点击</button>
function showThis(ctx){
    console.log(this);
    console.log(ctx);
}

如果想要这个DOM上的this,那么我们需要把this作为参数传进去

  • js绑定(对象形式)
var btn = document.getElementById("btn")
btn.onclick=function(){
    console.log(this);
}
onclick
  • js绑定(监听形式)
 document.getElementById("btn").addEventListener("click", function(){
    console.log(this);
 });
addEventListener

比如改变类的this

function Person () {
  this.name = '张三'
}
Person.prototype.talk = function () {
  console.log(this);
}
var Grey = new Person()
var btn = document.getElementById("btn")
btn.onclick=Grey.talk   //  <button id="btn" type="button" >点击</button>

相关文章

网友评论

      本文标题:this专题

      本文链接:https://www.haomeiwen.com/subject/bsgzdktx.html