JS学习笔记三

目录

一、this详解

        1、this原理

        2、使用场景

        1、普通函数的调用,this指向的是Window

        2、对象的方法,this指的是该对象


一、this详解

        1、this原理

        this是JavaScript的一个关键字,函数调用时才会出现;
        因为函数是在一定的环境中运行的,调用函数时肯定需要知道是[谁调用的]?就用到了this进行指向;
        那么this到底指向的是什么?
        this 既不指向函数自身,也不指函数的词法作用域,而是调用函数时的对象!

        2、使用场景

        1、普通函数的调用,this指向的是Window

var name = '卡卡';
function cat(){
  var name = '有鱼';
  console.log(this.name);//卡卡
  console.log(this);//Window {frames: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
}
cat(); //其实完整写法是window.cat()

       这里大家可能有疑问,不是说this指向的是调用函数的对象吗?cat()并没有对象出现啊,这个是因为在全局作用域中,window是根目录,一般可以省略,例如:alert()其实是 window.alert();

        2、对象的方法,this指的是该对象

        1、一层作用域链时,this指的该对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat:function(){
    console.log(this.name);//有鱼
  }
}
cat.eat();

       因为函数eat是由cat对象调用的,所以this指向的是cat本身,所以cat.name=有鱼;

        2、多层作用域链时,this指的是距离方法最近的一层对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat1:{
    name:'年年',
    eat2:function(){
      console.log(this.name);//年年
    }
  }
}
cat.eat1.eat2();

        eat2方法包含在两个对象cat、eat1中,但是紧挨着的eat1对象,所以this.name指的是eat1的属性name,即[年年]

        这里需要注意一个情况,如果cat.eat1.eat2这个结果赋值给一个变量eat3,则eat3()的值是多少呢?

var eat3 = cat.eat1.eat2;
eat3(); // 卡卡

        答案是[卡卡],这个是因为经过赋值操作时,并未发起函数调用,eat3()这个才是真正的调用,而发起这个调用的是根对象window,所以this指的就是window,this.name=卡卡。(可以理解为window对象中新增了一个eat3变量指向了eat1对象中的eat2方法,所以会存在window对象和window对象都有一个变量指向同一个方法)。

        3、构造函数的调用,this指的是实例化的新对象

var name = '卡卡';
function Cat(){
  this.name = '有鱼';
  this.type = '英短蓝猫';
}
var cat1 = new Cat();
console.log(cat1);// 实例化新对象 Cat {name: "有鱼", type: "英短蓝猫"}
console.log(cat1.name);// 有鱼

        4、apply和call调用时,this指向参数中的对象

var name = '有鱼';
function eat(){
  console.log(this.name);
}
var cat = {
  name:'年年',
}
var dog = {
  name:'高飞',
}

eat.call(cat);// 年年
eat.call(dog);// 高飞

        apply方法和call方法相当于改变了显式的修改了prototype原型

在这里插入图片描述

         5、匿名函数调用,指向的是全局对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat:(function(){
    console.log(this.name);//卡卡
  })()
}
cat.eat;

        这里提一下匿名函数调用方式,常用的有三种方法:

//①先用()包起来,然后再后面跟 (参数) 
(function(data){
  console.log(data);
})("222");

//②先后面跟(参数),然后再()包起来
(function(data){
  console.log(data);
}("333"));

//③正常函数格式,前面加 !
!function(data){
  console.log(data);
}("444");

        6、定时器中调用,指向的是全局变量

        常用的定时器有setInterval和setTimeout,拿setInterval举例子:

var name = '卡卡';
var cat = setInterval(function(){
  var name = '有鱼';
  console.log(this.name);// 卡卡
  clearInterval(cat);
},500);

        其实定时器的本质,也是一种匿名函数的形式。

        7、箭头函数调用
        如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象

var name = 'window';
var student = {
    name: '若川',
    doSth: function(){
        // var self = this;
        var arrowDoSth = () => {
            // console.log(self.name);
            console.log(this.name);
        }
        arrowDoSth();
    },
    arrowDoSth2: () => {
        console.log(this.name);
    }
}
student.doSth(); // '若川'
student.arrowDoSth2(); // 'window'

        8、DOM事件处理函数调用

<button class="button">onclick</button>
<ul class="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
    var button = document.querySelector('button');
    button.onclick = function(ev){
        console.log(this);
        console.log(this === ev.currentTarget); // true
    }
    var list = document.querySelector('.list');
    list.addEventListener('click', function(ev){
        console.log(this === list); // true
        console.log(this === ev.currentTarget); // true
        console.log(this);
        console.log(ev.target);
    }, false);
</script>

        onclick和addEventerListener是指向绑定事件的元素。一些浏览器,比如IE6~IE8下使用attachEvent,this指向是window。顺便提下:面试官也经常考察ev.currentTarget和ev.target的区别。ev.currentTarget是绑定事件的元素,而ev.target是当前触发事件的元素。比如这里的分别是ul和li。但也可能点击的是ul,这时ev.currentTarget和ev.target就相等了。

        3、总结

        ①普通函数的调用,this指向的是window
        ②对象方法的调用,this指的是该对象,且是最近的对象
        ③构造函数的调用,this指的是实例化的新对象
        ④apply和call调用,this指向参数中的对象
        ⑤匿名函数的调用,this指向的是全局对象window
        ⑥定时器中的调用,this指向的是全局变量window
        7.箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象
        8.onclick和addEventerListener是指向绑定事件的元素(ev.currentTarget)

参考文章

JS中的this详解_weixin_聂磐的博客-CSDN博客_js this

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值