菜鸟文章: this

20 阅读2分钟

this在我们js中是个非常重要的概念,设计到作用域,面向对象,函数,是一个综合性比较强的知识点。需要我们细致的去理解原理。才能真正弄懂js指向问题

1.this在不同地方的指向

    //this在函数中的指向
    function fn(){
        console.log(this);
    }
​
    fn(); //window
​
​
​
   //在对象中的指向
​
   let info = {
​
       name:'鲁班',
       age:18,
       eat:function(){
​
           console.log(this);  //info
​
       }
​
   }
​
   info.eat();
​
  //在构造函数中的指向
​
   function Person(name,age){
       this.name = name;
       this.age = age;
​
       console.log(this);  //实例对象
   }
​
   let person  = new Person('鲁班',20);
 
  //this在原型中的指向
​
    function Person(name,age){
​
    }
​
    Person.prototype.eat = function(){
​
        console.log(this);   //实例对象
​
    }
​
    let person = new Person();
​
    person.eat();  
​
​
    //this在定时器中的指向
​
    setInterval(function(){
​
        console.log(this);  //window
​
    },1000);
​
​
​

案例1:(this指向问题)

   function Person(){
       this.count = 30;
       return {
           count:40
       }
    }
​
    let person = new Person();
    
   
    console.log(person.count);  //40

案例2:(this指向问题)

    function Remark(btn){
        this.btn = btn;
        this.count = 0;
        this.timer = null;
    }
​
    Remark.prototype.bindClick  = function(){
          let that = this;   //用对象保存当前之前
​
       this.btn.addEventListener('click', function(){
               
           
​
        that.timer = setInterval(function(){
             
            
​
             that.count++;
             
             if(that.count === 10){
                 clearInterval(that.timer);
             }
​
             console.log(that.count);
​
         },1000);
​
       });
        
        
    }
​
  
    let btn  = document.querySelector(".btn");
​
    let remark =  new Remark(btn);
​
      remark.bindClick();

2.改变this指向

call(对象,参数1,参数2,参数3.....);

apply(对象,[参数1,参数2,参数3.......]);

bind(对象,参数1,参数2,参数3.....);

function Person(name,age){
        this.name = name;
        this.age  = age;
    }
​
    function Student(name,age,classID){  
​
​
        //改变this指向  也可以用apply替换      区别:没啥区别,效果都是一样的,  只是传参方式不同而已
        //Person.call(this,name,age)
​
        Person.apply(this,[name,age]);
​
        this.classID = classID;
​
    }
​
​
    let person = new Student("鲁班",20,'001');
​
    console.log(person.name);
​
​
//    call和apply作用是改变this指向。  也相当于函数调用
​
     function fn(){
         console.log('今天夜宵吃啥?');
     }
​
​
     fn.call();
​
     fn.apply();
​
//函数和对象
​
    var  Myname  = "鲁班";
​
​
     let  info = {
         Myname:"鲁班七号",
         age:18
     }
     
     function fn(){
​
         console.log(this.Myname);
​
     }
​
     fn();  //鲁班;
​
     fn.call(info);

bind

    //bind也有改变this指向的功能  没有直接函数调用功能
​
    var name = "鲁班七号";
​
    function fn(){
​
        console.log(this.name);
​
    }
​
     let fn2  = fn.bind();
     
     fn2();
​
    let info = {
        name:'鲁班',
        age:18
    }

优化案例2

3.严格模式(拓展知识点)

概念:除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。

目的:

1.消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

2.消除代码运行的一些不安全之处,保证代码运行的安全;

3.提高编译器效率,增加运行速度;

4.为未来新版本的Javascript做好铺垫。

//未定义的变量会报错
    "use strict";
​
     tel = 123456789;
​
     console.log(tel);
​
​
//不支持width语法
 "use strict";
   let obj  = {
       name:'鲁班',
       age:18,
       sex:'男'
   }
​
   with(obj){
​
     console.log(name);
     console.log(age);
     console.log(sex);
​
   }
​
//eval 独立作用域
 "use strict";
   
  eval("var abc = 12312");
​
  console.log(abc);
​
​
//arguments作为静态副本
 "use strict";
   
 (function(num){
      arguments[0] = 20;
      console.log(num);
 })(1)
​