IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JS-part11.1-this指向 / 改变this指向 -> 正文阅读

[JavaScript知识库]JS-part11.1-this指向 / 改变this指向

this指向

+ 定义:
  => this 是一个使用在作用域内部的关键字
  => 全局很少有, 大部分是在函数内部使用
+ 指向:
  => 全局使用: window
  => 函数使用: **不管函数怎么定义, 不管函数在哪定义, 只看 this 在函数里的调用(箭头函数除外)**
    -> 普通调用(直接调用/全局调用)
      + 函数名(): this -> window
    -> 对象调用
      + xxx.函数名(): this -> 点前面是谁就是谁
    -> 定时器处理函数
      + setTimeout(function(){}, 0): this -> window
      + setInterval(function(){}, 0): this -> window
    -> 事件处理函数
      + xxx.onclick = function(){}: this -> 事件源(绑定在谁身上的事件, 而不是由谁触发)
      + xxx.addEventListener('', function(){}): this -> 事件源
    -> 自执行函数
      + (function(){})(): this -> window
function fn(){
    console.log(this)
}
fn() // 普通调用 this -> window

var obj = {
    // 把 fn 存储的地址赋值给了 obj 的 f 成员
    // 从现在开始, obj.f 和全局变量 fn 指向同一个函数空间
    f: fn,
    name: '我是 obj 对象'
}

obj.f() // 对象调用 this -> obj

// 把 fn 函数当作定时器处理函数使用
setTimeout(fn, 0)  // 定时器处理函数 this -> window
setTimeout(obj.f, 0)  // 定时器处理函数 this -> window

var div = document.querySelector('div')
// 当点击 div 的时候, 执行 obj.f 这个函数
div.onclick = obj.f  // 事件处理函数 this -> div

div.addEventListener('click', obj.f)  // 事件处理函数 this -> div
function fn(){
    console.log(this)
}

fn() // window

setTimeout(function(){
    fn()  // window
},0)

var div = document.querySelector('div')
div.onclick = function(){
    console.log(this)  // div
    fn()   // window
}
var div = document.querySelector('div')
div.onclick = function(){
    function f(){
        console.log(this)
    }
    f()  // window
}
var obj = {
    name: '我是 obj 对象',
    fn: function(){ console.log(this) }
}

obj.fn()  // this -> obj

// 把 obj 里面 fn 成员存储的函数地址赋值给了全局变量 f
// 全局变量 f 和 obj.fn 指向同一个函数空间
var f = obj.fn

f() // this -> window
var obj = {
    name: '我是 obj 对象',
    fn: function(){ 
        console.log(this) 
        function fun(){
            console.log(this)
        }
        fun() // window
    }
}

obj.fn() // obj

改变this指向

改变 this 指向
  + this 有他本身的指向性
  + 不管你本身指向哪里, 我让你指向谁, 你就指向谁
  + 三个方法
    1. call()
    2. apply()
    3. bind()

1. call()

+ 使用方法: 直接连接在函数名后面使用就行
  + 语法:
    -> fn.call()
    -> obj.fn.call()
  + 参数:
    -> 第一个参数, 就是函数内部的 this 指向
    -> 第二个参数开始, 依次给函数传递参数
  + 特点:
    -> 会立即执行函数(不适合用作定时器处理函数或者事件处理函数)
  + 作用: 伪数组借用数组方法
function fn(a, b){
   console.group('fn 函数')
   console.log(this)
   console.log(a)
   console.log(b)
   console.groupEnd()
}

var obj = {
   name: '我是 obj 对象'
}

fn(10, 20)  // this -> window

// 1. call()
// 使用 call 方法去调用 fn 函数, 把函数内部的 this 指向 改变成 obj
// fn.call(obj)   // obj
// fn.call([123, 456])   // [123, 456]
fn.call(obj, 100, 200)

在这里插入图片描述

/*
  小例子
    + call 方法的作用: 伪数组借用数组方法
*/
function f(){
    console.log(arguments)

    // 伪数组用不了数组常用方法
    // 但是数组可以
    // var res = arguments.every(function(t){ return t >= 20 }) // Uncaught TypeError: arguments.every is not a function

    // every() 方法的调用, 需要接收一个函数作为实参
    // arguments.every() 是因为 arguments 没有 every 方法, 所以报错

    // 数组在调用 every 方法
    // every 里面的 this 指向前面的数组
    // 利用 call 方法来执行数组的 every 函数
    // 第一个参数是 every 里面的 this 指向
    // 原先 every 的 this 指向指向数组的时候, 遍历查看数组
    // 现在 every 的 this 指向 arguments, 遍历查看 arguments
    // call 的第二个参数是给函数传递参数的
    // 函数function(t){return t >= 20})就是传递给 every 方法里面的参数
    var res = [].every.call(arguments, function(item){return item >= 8 })  
    console.log(res)  // true
}

f(10, 20, 30, 40, 50)

2. apply()

+ 使用方法: 就直接连接在函数名后面使用
+ 语法:
    -> fn.apply()
    -> obj.fn.apply()
  + 参数:
    -> 第一个参数, 就是函数内部的 this 指向
    -> 第二个参数, 是一个数组或者伪数组都行, 里面的每一项依次给函数传递参数
  + 特点:
    -> 会立即执行函数(不适合用作定时器处理函数或者事件处理函数)
  + 作用: 可以以数组的形式给某些功能函数传参
    -> Math.max()
// 2. apply()
// 使用 apply 方法调用 fn 函数, 把函数内部的 this 指向 改变成 obj
fn.apply(obj, [1000, 'world'])
/*
  小例子
    + apply 方法的作用: 以数组的形式给某些功能函数传参
*/
var arr = [100, 23, 45, 59, 91]

//     var res = Math.max(100, 23, 45, 59, 91)
var res = Math.max.apply(null, arr)

console.log(res)  // 100

3. bind()

+ 使用方法: 就直接连接在函数名后面使用
+ 语法:
    -> fn.bind()
    -> obj.fn.bind()
  + 参数:
    -> 第一个参数, 就是函数内部的 this 指向
    -> 从第二个参数, 依次给函数传递参数
  + 特点:
    -> 不会立即执行函数
    -> 会返回一个新的函数, 一个已经被改变好 this 指向的函数
  + 作用: 改变事件处理函数或者定时器处理函数的 this 指向 或 传参, 改 this 指向很少用, 一般用来传参
// 3. bind()
// 使用 bind 方法改变 fn 函数的 this 指向
// res 是一个 fn 函数的克隆版, 只不过里面的 this 被锁死了, 指向 obj
var res = fn.bind(obj, 'hello', 'world')
// console.log(res)
res()
 /*
   小例子
     + bind 方法的作用: 改变事件处理函数或者定时器处理函数的 this 指向
 */
var div = document.querySelector('div')

function handler(a, b){
    console.log(this)     // obj
    console(a, b)
}

var obj = { name: '我是 obj 对象' }

// call 和 apply 不合适, 因为还没等到点击呢, 函数就执行了

// 不会把 handler 函数执行, 而是返回一个新的锁死了 this 指向的函数
// var res = handler.bind(obj)
// 调用的是一个被 bind 锁死 this 指向的函数
div.onclick = handler.bind(obj, 100, 200)
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:24:58  更:2021-09-04 17:25:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:45:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码