首页 > 编程语言 >JavaScript(9) ----this指向问题,bind,call,apply等方法

JavaScript(9) ----this指向问题,bind,call,apply等方法

时间:2024-07-13 09:54:34浏览次数:11  
标签:console name bind JavaScript ---- call apply log

目录

this指向问题

全局函数调用:

对象方法调用:

构造函数调用:

事件处理:

箭头函数:

setTimeout和setInterval

7.使用call、apply或bind

call 方法

apply 方法

bind 方法

总结


this指向问题

  • 全局函数调用:在全局作用域中调用函数时,this指向全局对象(浏览器中是window对象)。

function sayHello() {
    console.log(this);
}
sayHello(); // 输出:Window {...}
  • 对象方法调用:当函数作为对象的方法被调用时,this指向调用该方法的对象。


const person = {
    name: 'Alice',
    greet: function() {
        console.log('Hello, ' + this.name);
    }
};
person.greet(); // 输出:Hello, Alice
  • 构造函数调用:使用new关键字创建对象时,this指向新创建的对象。

function Person(name) {
    this.name = name;
}
const bob = new Person('Bob');
console.log(bob.name); // 输出:Bob
  • 事件处理:在事件处理函数中,this指向触发事件的元素。

<button id="myButton">Click me!</button>
<script>
document.getElementById('myButton').addEventListener('click', function() {
    console.log(this); // 输出:button#myButton
});
</script>
  • 箭头函数:箭头函数没有自己的this上下文,它会捕获其所在上下文的this值,作为自己的this值,除非它是在全局作用域中定义的。

const obj = {
    arr: [1, 2, 3],
    sum: () => {
        return this.arr.reduce((a, b) => a + b, 0);
    }
};
console.log(obj.sum()); // 输出:6
  • setTimeoutsetInterval

在JavaScript中,setTimeout和setInterval函数用于设置定时器,分别用于延迟执行和重复执行指定的函数。与普通函数调用不 同,setTimeout和setInterval中的回调函数不会自动绑定到任何特定的对象上,它们的this值通常指向全局对象(在浏览器中是window对象),除非显式地使用call、apply或bind方法来改变this的值。

function delayedGreeting() {
    console.log('Hello, ' + this.name);
}

const person = { name: 'Dave' };

// 直接使用setTimeout,this将指向全局对象
setTimeout(delayedGreeting, 1000); // 输出:Hello, undefined(因为this.name是undefined)

// 使用bind来绑定this
setTimeout(delayedGreeting.bind(person), 1000); // 输出:Hello, Dave
  • 7.使用call、apply或bind:这些方法允许你显式地设置this的值。

function sayName(name) {
    console.log('My name is ' + this.name + ' and you are ' + name);
}
const person = { name: 'Alice' };
sayName.call(person, 'Bob'); // 输出:My name is Alice and you are Bob

在JavaScript中,call、apply和bind这三个方法都可以用来显式地设置this的值,它们主要区别在于参数传递的方式不同。

call 方法

call方法调用一个函数,将this关键字设置为指定的对象,并在调用时将其余参数逐个传递给该函数。

语法:

functionName.call(thisArg, arg1, arg2, ...);

示例:

function greet(greeting, punctuation) {
    console.log(greeting + ' ' + this.name + punctuation);
}

const person = { name: 'Alice' };

// 使用call方法调用greet函数,将this设置为person对象
greet.call(person, 'Hello', '!'); // 输出:Hello Alice!

// 2. call的应用场景 - 检测数据类型
    // 2.1 typeof 检测数据类型不够精确的
    console.log(typeof '123') // string
    console.log(typeof []) // object
    console.log(typeof null) // object

    // 2.2 Object.prototype.toString()  返回的结果是[object xxx类型]
    // console.log(Object.prototype.toString('123')) //  [object Object]
    console.log(Object.prototype.toString.call('123'))  // [object String]
    console.log(Object.prototype.toString.call(123))  // [object Number]
    console.log(Object.prototype.toString.call([]))  // [object Array]
    console.log(Object.prototype.toString.call(null))  // [object Null]

apply 方法

apply方法与call方法类似,但它接受一个参数数组,而不是多个参数。

语法:

functionName.apply(thisArg, [argsArray]);

示例:


function sum(a, b) {
    console.log(this.name + ' calculates the sum as ' + (a + b));
}

const person = { name: 'Bob' };

// 使用apply方法调用sum函数,将this设置为person对象,并传递参数数组
sum.apply(person, [5, 7]); // 输出:Bob calculates the sum as 12


    // 2. 使用场景- 求数组的最大值/最小值
    console.log(Math.max(...[1, 2, 3]))  // 3

    // apply 或者 call 如果不需要改变this指向 写 null 
    console.log(Math.max.apply(null, [8, 2, 3]))  // 8
    console.log(Math.min.apply(null, [8, 2, 3]))  // 2

bind 方法

bind方法创建一个新的函数,在调用时将this关键字设置为提供的值,第一个参数之后的所有参数都将作为新函数的参数,供调用时使用。

语法:

let boundFunc = functionName.bind(thisArg, arg1, arg2, ...);

示例:

function sayHello() {
    console.log('Hello ' + this.name);
}

const person = { name: 'Carol' };

// 使用bind方法创建一个新的函数,将this设置为person对象
const sayHelloToCarol = sayHello.bind(person);

// 调用新创建的函数
sayHelloToCarol(); // 输出:Hello Carol


    // 2. 使用场景 - 不需要调用函数,但是又想改变函数内部的this指向

    // 1. 发送短信5秒倒计时业务
    const codeBtn = document.querySelector('.code')
    let flag = true  // 开关变量,用来防止多次点击
    codeBtn.addEventListener('click', function () {
      if (flag) {
        // 1.2 利用定时器做倒计时效果 setInterval 
        let i = 5
        // 点击之后立马变化文字
        this.innerHTML = `05秒后重新获取`
        // 定时器
        let timerId = setInterval(function () {
          i--
          this.innerHTML = `0${i}秒后重新获取`

          // 1.3 时间到了 就显示文字为 重新获取
          if (i === 0) {
            this.innerHTML = `重新获取`
            // 停止定时器
            clearInterval(timerId)
            flag = true
          }
        }.bind(this), 1000)
        // 关闭开关 
        flag = false
      }
    })

bind方法返回的是一个新的函数,这意味着你可以将这个新函数赋值给一个变量,或者将它作为回调函数传递给其他函数。

总结

  • call和apply方法都是立即执行函数。
  • call接受参数列表,apply接受一个参数数组。
  • bind返回一个新的函数,可以稍后执行。

这些方法在JavaScript中非常有用,特别是在需要控制函数内部this上下文的场景中。

标签:console,name,bind,JavaScript,----,call,apply,log
From: https://blog.csdn.net/yanminghe66666/article/details/140394731

相关文章

  • abc134E - Sequence Decomposing
    abc134E-SequenceDecomposing题意:给定一个序列,将其划分成若干个不相交的严格上升子序列,求划分的最小的子序列数量。题解:我们可以定义严格偏序关系,\(i\precj\)当\(i<j\)且\(a_i<a_j\),也就是我们要将整个序列划分成若干个链。根据Dilworth’stheorem,最小链覆盖数=最大......
  • C++中的可见性 指针 笔记
    含义:谁能看到他们谁能调用?谁能使用?可见性的修饰符:private含义:只有其所在的类可以访问,被修饰的变量但是friend关键字可以让类或者函数成为朋友(友元)可以在别处访问私有成员protected含义:所在的类和层次结构中的所有子类可以访问这些符号例子:classprintable{prot......
  • 第二部分:关键技术领域的开源实践【容器化】
    企业开源中的容器化是一个重要的发展趋势,它在支撑企业持续信息化方面能发挥多重关键作用。以下是容器化对企业持续信息化的主要影响:标准化和一致性:容器化提供了一种标准化的方式来打包和部署应用程序,无论是在开发、测试还是生产环境中,都能确保一致的运行环境,减少“在我的机器......
  • [RootersCTF2019]I_<3_Flask 1
    考点,注入点探测,ssti,jinja模板打开题目后可以看到是flask,不难联想到是模板注入,但是我们还是不知道注入点的参数,所以我们可以用arjun去进行探测配置方法pip3installarjunarjun-u网址之后我们先尝试注入{{7*'7'}}可以通过回显判断出是jinjia模板直接上fenjing直接命令......
  • 11-Properties基本介绍
    11-Properties基本介绍Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。(因为继承Properties,所以键值对不可以为null)Properties类使用特点和Hashtable类类似,但是请注意Properties类的键值类型都为String。虽然可以直接调用......
  • P2482 [SDOI2010] 猪国杀 代码(暂未完成)
    #include<bits/stdc++.h>usingnamespacestd;namespacework{constintmaxPlayerNumber=11;intn,m,top=1;//玩家数,牌堆中的牌数,目前的牌堆顶unordered_map<string,int>transCard;//牌型编号unordered_map<string,int>transRole;//角色编号vector<int>c......
  • 计算思维
           ......
  • 【云岚到家】-day05-7-项目迁移-活动管理
    【云岚到家】-day05-7-项目迁移-活动管理5项目迁移-活动管理5.1迁移目标5.2签到活动5.2.1需求分析5.2.2系统设计5.2.2.1表设计5.2.2.2接口设计5.2.2.3如何计算连续签到天数5.2.2.4如何获取匹配签到奖励规则5.2.2.5签到代码5.3优惠券活动5.3.1需求分析5.3.2......
  • PTE
    0环境及工具操作系统:Windows10,Kali2024,CentOS6.9工具:Burpsuite,AntSword-蚁剑,1基础题目之SQL注入审题:![[课堂/实训/assets/Pastedimage20240709215659.png]]发现一点关联点:![[课堂/实训/assets/Pastedimage20240709215740.png]]尝试修改id以达到SQL注......
  • MySQL8.0 新特性函数索引
    MySQL8.0中的函数索引(Function-BasedIndex)是一种高级索引特性,它允许数据库管理员或开发者对表中的列执行表达式计算后的结果进行索引,而不是直接对列值或列的前缀值进行索引。这种索引技术可以显著提高查询性能,特别是在需要对列值进行复杂计算或转换的查询场景中。MySQL8......