JavaScript this指向
程序员文章站
2022-07-03 10:26:07
JavaScript this指向一、回顾作用域1、什么是作用域一个变量可以使用的范围2、作用域分类全局作用域:一个 html 页面就是一个全局作用域局部作用域(私有作用域):只有函数生成私有作用域3、作用域的上下级关系写在哪个作用域里面的私有作用域,就是哪个作用域的子级作用域this 指向(重点)一、定义:this 是一个使用在作用域里面的关键字作用域里面:要么写在全局,要么写在函数里面是个关键字:定义变量的时候,不能用 var this,不需要定义,直接使用就可以了...
JavaScript this指向
一、回顾作用域
1、什么是作用域
- 一个变量可以使用的范围
2、作用域分类
- 全局作用域:一个 html 页面就是一个全局作用域
- 局部作用域(私有作用域):只有函数生成私有作用域
3、作用域的上下级关系
- 写在哪个作用域里面的私有作用域,就是哪个作用域的子级作用域
this 指向(重点)
一、定义:this 是一个使用在作用域里面的关键字
- 作用域里面:要么写在全局,要么写在函数里面
- 是个关键字:定义变量的时候,不能用 var this,不需要定义,直接使用就可以了
二、this 代表什么意思
- 当你在全局作用域使用 this 的时候,this === window
- 表示全局的意思
- 一般很少在全局直接使用
- 当你在函数里面使用的时候,也就是在私有作用域里面使用的时候
- 在 JS 里面,很多的函数都会用到 this
- 面试的时候,很多坑都是会问你 this 指向谁而出现的
三、函数内部的 this 指向(背)
强行改变 this 指向
- 因为每一种函数调用方式都有自己的 this 指向
- 强行改变:不管你本身指向哪里,我让你指哪里,你就得指向哪里
一、call( )
- 使用方式:直接跟在函数名后面使用就可以了
调用方式 | 强行改变 this 指向的调用方式 |
---|---|
fn( ) | fn.call( ) |
obj.fn( ) | obj.fn.call( ) |
-
参数:call(你要改变的 this 指向, 给函数传递参数, 给函数传递参数, …)
- 第一个参数:你要改变的 this 指向,不传递或者写一个 null 都是表示 window 的意思
- 第二个参数开始:依次给函数传递参数
-
作用:就是改变函数内部的 this 指向
-
特点:直接调用函数,写完以后,函数就执行了
// call()
function fn(a, b, c) {
console.log(this) // this 指向
console.log(a)
console.log(b)
console.log(c)
}
fn(10, 20, 30) // 标准调用 this -> window
console.log('===============================')
// 使用 call 改变 this 指向
// 我准备的几个数据, 为了让你看到 this 指向确实改了
var obj = { name: '我是 obj 对象' }
var arr = [1, 2, 3, 4, 5]
var num = 100
var str = 'hello world'
// 本次调用 fn 的时候, 把函数内部的 this 改变成了 obj
// 100 是传递进去的第一个参数
// 200 是传递进去的第二个参数
fn.call(obj, 100, 200, 300) // this -> obj
console.log('===============================')
// 本次调用 fn 的时候, 把函数内部的 this 改成了 arr
// 100 是传递进去的第一个参数
// 200 是传递进去的第二个参数
fn.call(arr, 100, 200, 300) // this -> arr
console.log('===============================')
// 本次调用 fn 的时候, 把函数内部的 this 改成了 num
// 100 是传递进去的第一个参数
// 200 是传递进去的第二个参数
fn.call(num, 100, 200, 300) // this -> num
console.log('===============================')
// 本次调用 fn 的时候, 把函数内部的 this 改成了 str
// 100 是传递进去的第一个参数
// 200 是传递进去的第二个参数
fn.call(str, 100, 200, 300) // this -> str
console.log('===============================')
// 本次调用 fn 的时候, 把函数内部的 this 改成了 100
// 200 是传递进去的第一个参数
// 第二个参数没有了
fn.call(100, 200) // this -> 100
二、apply( )
- 使用方式:直接跟在函数名后面使用就可以了
调用方式 | 强行改变 this 指向的调用方式 |
---|---|
fn( ) | fn.apply( ) |
obj.fn( ) | obj.fn.apply( ) |
- 参数:apply(你要改变的 this 指向, [给函数传递参数1, 给函数传递参数2, …])
- 第一个参数:你要改变的this 指向,不传递或者写一个 null 都是表示 window 的意思
- 第二个参数:是一个数组或者伪数组都可以,里面的每一项依次是给函数传递参数
- 作用
- 改变 this 指向
- 改变函数传递参数的方式
- 特点:直接调用函数,写完以后,函数就执行了
// apply
function fn(a, b) {
console.log('this: ', this)
console.log('第一个参数: ', a)
console.log('第二个参数: ', b)
console.log('================================')
}
// 准备几个数据用于改变 this 指向的时候使用
var obj = { name: '我是 obj 对象' }
var arr = [10, 20, 30, 40, 50]
var reg = /^abcd$/
var time = new Date()
// 基础调用
fn(10, 20)
// apply 改变 this 指向
// 本次调用 fn 的时候, 把函数内部的 this 指向改变成 obj
// 数组中 [0] 是给 fn 函数的第一个参数
// 数组中 [1] 是给 fn 函数的第二个参数
fn.apply(obj, [100, 200])
// 本次调用 fn 的时候, 把函数内部的 this 指向改变成 arr
// 数组中 [0] 是给 fn 函数的第一个参数
// 数组中 [1] 是给 fn 函数的第二个参数
fn.apply(arr, [1000, 2000])
// 本次调用 fn 的时候, 把函数内部的 this 指向改变成 reg
// 数组中 [0] 是给 fn 函数的第一个参数
// 数组中 [1] 是给 fn 函数的第二个参数
fn.apply(reg, [10000, 20000])
// 本次调用 fn 的时候, 把函数内部的 this 指向改变成 time
// 数组中 [0] 是给 fn 函数的第一个参数
// 数组中 [1] 是给 fn 函数的第二个参数
fn.apply(time, ['hello', 'world'])
三、bind( )
- 使用方式:直接跟在函数名后面使用就可以了
调用方式 | 强行改变 this 指向的调用方式 |
---|---|
fn( ) | fn.bind( ) |
obj.fn( ) | obj.fn.bind( ) |
- 参数:blind(你要改变的 this 指向, 给函数传递的参数1, 给函数传递的参数2, …)
- 第一个参数:你要改变的 this 指向,不传递或者写一个 null 都是表示 window 的意思
- 第二盒参数开始:依次给函数传递方式
- 作用:
- 改变 this 指向
- 改变一个不需要立即执行的函数的 this 指向
- 特点:
- 不会直接调用函数,写完以后函数没有执行,而是返回一个新的函数,一个改变好了 this 指向的函数
- 一个已经被改变一次 this 指向的新函数不能被再次改变
- 例子:事件
- div.onclick = fn —>> fn内部的 this 指向 div
- 我想修改一下,触发点击行为的时候,不想函数里面的 this 指向 div
- 如果写成 div.onclick = fn.call(window),点击的时候就没有函数执行了
- 你绑定事件的时候就把函数执行了,而不是点击的时候再执行
// bind()
function fn(a, b) {
console.log('this: ', this)
console.log('第一个参数: ', a)
console.log('第二个参数: ', b)
console.log('================================')
}
// 准备几个数据用于改变 this 指向的时候使用
var obj = { name: '我是 obj 对象' }
var arr = [10, 20, 30, 40, 50]
var reg = /^abcd$/
var time = new Date()
// 直接调用
fn(10, 20) // 函数调用了
// 使用 bind 改变一下 this 指向
// 本次 bind 会把 fn 函数复制一份, 把里面的 this 改变成 obj
// 100 是给 fn 函数传递的第一个参数
// 200 是给 fn 函数传递的第二个参数
// 注意: 此时不会直接调用函数, 而是会有一个返回值出现
// res 就是一个新的函数, 和 fn 函数一模一样的代码, 只是里面的 this 指向 obj
var res = fn.bind(obj, 100, 200)
// res() 就是再调用一个和 fn 一模一样的函数, 只不过 this 改变了
res()
// 本次 bind 回把 fn 函数复制一份, 把里面的 this 改变成 time
var res2 = fn.bind(time, 1000, 2000)
res2()
本文地址:https://blog.csdn.net/DingDing_Zhang/article/details/107391956
推荐阅读
-
JavaScript观察者模式(publish/subscribe)原理与实现方法
-
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
-
JavaScript中 ES6变量的结构赋值
-
JavaScript的Object.defineProperty详解
-
JavaScript解决浮点数计算不准确问题的方法分析
-
javaScript练习:js和flash
-
JavaScript开发中nodejs8.9.4安装方法
-
JavaScript的作用域和作用域链
-
JavaScript高级程序设计第五章引用类型——RegExp类型
-
Javascript中函数绑定bind()的实例讲解