zoukankan      html  css  js  c++  java
  • 函数内部的this指向以及如何改变函数内部的this指向

    一、函数内部的this指向

    调用方式 this指向
    普通函数调用 window
    构造函数调用 实例对象
    对象的方法调用 该方法所属对象
    事件绑定方法 绑定事件对象
    定时器函数 window
    立即执行函数 window

    1、普通函数调用

    普通函数的this指向window
    1 function fun() {
    2     console.log('普通函数的this' + this);
    3 }
    4 fun();

    2、构造函数调用

    构造函数this指向ldh这个实例对象,原型对象里面的this指向的也是ldh这个对象

    1 function Star() {};
    2 Star.prototype.sing = function() {};
    3 var ldh = new Star();

    3、对象的方法调用

    对象的方法的this指向的是对象o

    1 var o = {
    2     sayHi: function() {
    3         console.log('对象方法的this' + this);
    4     }
    5 }
    6 o.sayHi();

    4、事件绑定方法

    绑定事件函数this指向的是函数的调用者btn这个按钮对象

    1 var btn = document.querySelector('button');
    2 btn.onclick = function() {
    3     console.log('绑定事件函数的this' + this);
    4 
    5 }

    5、定时器函数

    定时器函数this指向的是window

    1 setTimeout(function() {
    2     console.log('定时器函数的this' + this);
    3 }, 1000);

    6、立即执行函数

    立即执行函数this指向的是window

    1 (function(){
    2     console.log('立即执行函数的this'+this);
    3 })();

     

    二、改变函数内部的this指向的三种方法

    1、call方法

    call()方法可以调用函数,还可以改变函数内的this指向,它的主要作用是可以实现继承

    fun.call(thisArg,arg1,arg2,....)

    这里将fun函数的this指向o

    1 var o = {
    2     name: 'Andy'
    3 }
    4 
    5 function fun(a, b) {
    6     console.log(this);
    7     console.log(a + b);
    8 }
    9 fun.call(o, 1, 2);

    将父构造函数里的this指向子构造函数的实例对象(构造函数的this指向它的实例对象)

     1 function Father(uname, age, sex) {
     2     this.uname = uname;
     3     this.age = age;
     4     this.sex = sex;
     5 }
     6 
     7 function Son(uname, age, sex) {
     8     Father.call(this, uname, age, sex);
     9 }
    10 var son = new Son('ldh', 18, 'male');
    11 console.log(son);

    2、apply方法

    fun.apply(thisArg,[argsArray])(传递的值必须包含在数组里)

    apply()方法可以调用函数,还可以改变函数内的this指向,但它的参数必须是数组(伪数组)

    1 var arr = [1, 33, 22, 44, 12];
    2 var max = Math.max.apply(Math, arr);
    3 var min = Math.min.apply(Math, arr);
    4 console.log(max, min);

    3、bind方法(用的最多)

    bind()方法不会调用函数,但是可以改变函数内部this指向

     fun.bind(thisArg,arg1,arg2,....)

     1 var o = {
     2     name: 'Andy'
     3 }
     4 
     5 function fun(a, b) {
     6     console.log(this);
     7     console.log(a + b);
     8 }
     9 var f = fun.bind(o, 1, 2);
    10 f();
    下面的小案例是点击按钮后按钮禁用,直到三秒后开启按钮
    虽然定时器函数里的this指向window,但是bind(this)里面的this是在定时器函数的外面绑定的,这个this又在btns[i].onclick这个函数里面,所以这个this指向的就是btns对象
    为什么这里的this.disabled的this不用btns[i]呢,因为定时器是在3秒后执行,而for循环立马执行,这里有三个按钮,则i为3
    1 var btns = document.querySelectorAll('button');
    2 for (var i = 0; i < btns.length; i++) {
    3     btns[i].onclick = function() {
    4         this.disabled = true;
    5         setTimeout(function() {
    6             this.disabled = false;
    7         }.bind(this), 3000);
    8     }
    9 }

    3、call、apply、bind总结

    相同点:都可以改变函数内部的this指向

    区别:

    1.call和apply会调用函数,并且改变函数内部的this指向

    2.call和apply传递的参数不一样,apply必须以数组形式

    3.bind不会调用函数,但是会改变函数内部的this指向

    主要应用场景:

    1.call主要用作继承

    2.apply经常跟数组有关,比如借助数学对象实现数组中的最大最小值

    3.bind可用于改变定时器内部的this指向

  • 相关阅读:
    批量计算(batch computing)、流式计算(stream computing)、交互计算(interactive computing)、图计算(graph computing)
    ETL相关 ELT
    添加AD验证(域身份验证)到现有网站
    android开发导包升级到androidx踩坑记录【转载】
    Android Support v4v7v13和AndroidX理解【转载】
    架构师的成长之路初片~linux-基本防护措施
    架构师的成长之路初片~nginx优化篇
    架构师的成长之路初片~linux-监控脚本
    架构师的成长之路初片~Virtual-自定义容器
    架构师的成长之路初片~Virtual-容器和镜像常用的管理命令
  • 原文地址:https://www.cnblogs.com/helloCindy/p/12261519.html
Copyright © 2011-2022 走看看