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知识库 -> JavaScript高级 |彻底搞清this指向问题 -> 正文阅读

[JavaScript知识库]JavaScript高级 |彻底搞清this指向问题

本文已收录于专栏
?? 《JavaScript》??

this指向问题

this 指向问题 一般情况下 this 的最终指向是那个调用它的对象。

①在全局作用域下或者普通函数中 this 指向全局对象window,包括定时器。

因为在全局作用域下,变量和函数都是window的属性或者方法,所以也就是说他们的调用者就是 window。

console.log(this)
function fun(){
	console.log(this);
}
本质:
window.function fun(){
	console.log(this);
}
setTimeout(function(){
	console.log(this);
},1000);

本质:
window.setTimeout(function(){
	console.log(this);
},1000);

②方法调用中:谁调用this就指向谁。

调用对象o里面的方法

this指向对象o

var o = {
  sayHi:fuction(){
  console.log(this);
  //this 指向的是 o 这个对象
}
}
o.sayHI();

调用 btn 按钮对象

this 指向的是 btn

var bth = document.querySelector('button');

//传统注册事件方法
btn.onclick = function(){
  console.log(this);
}

//事件监听
btn.addEventListener('click',function(){
  console.log(this);
})

③构造函数中this指向构造函数中的实例。

在构造函数里调用this

指向的是 Fun的实例对象 fun

function Fun(){
  console.log(this);
}
var fun = new Fun();

this 绑定规则

默认绑定

**独立函数调用都是指向 window **
独立的函数调用我们可以理解成函数没有被绑定到某个对象进行调用

  1. 普通函数被独立调用

window是它的绑定对象

function foo(){
	console.log("foo:",this);
}
foo();
  1. 函数定义在对象里,但是被单独调用

在 ②这种情况中 虽然函数定义在了对象里面,但还是被单独调用,所以此时this 的绑定对象 仍是 window
在 ①这种情况中 函数定义在了对象里面,而且是被对象调用的,所有此时this 的绑定对象是 object
所以 this 的绑定对象,与函数的声明位置没有关系。

var obj = {
  name:"why",
  bar:function(){
    console.log("bar:",this)
  }
}
① obj.bar() 
//此时 this 指向的是 objectvar baz = obj.bar
baz();
// 此时 this 指向的是 window
  1. 严格模式下,独立调用的函数中的this 指向都是 undefined

一般打包工具会自动将js文件设置成 严格模式,这样可以规避一些低级错误。

"use stric"

function foo(){
	console.log("foo:",this);
}
foo();

var obj = {
  name:"why",
  bar:function(){
    console.log("bar:",this)
  }
}
 var baz = obj.bar
baz();

总结:

  • 用 this 代替 window 会比较危险,所以建议直接window来写。
  • 独立函数调用都是指向 window 的!
function foo(){
	console.log("foo:",window);
}
foo();

隐式绑定

通过某个对象进行调用,即调用位置是某个对象发起的函数调用。

前提:必须在调用的对象内部有一个函数的引用,(比如一个属性)

简单来说就是:将函数赋值给了对象的某个属性,然后通过调用对象的这个属性的方式调用函数就是隐式绑定

function foo(){
	console.log("foo函数:",this);
}

var obj = {
	bar:foo
  //将上面声明的那个 foo()函数 赋值给这个 bar 属性
}

obj.bar();
// 调用 obj  对象中的 bar 属性

显式绑定

与隐式绑定不同,显式绑定是通过call()等方法调用自己指定好的this指向的函数。

var obj = {
  name:"why";
}

function foo(){
  console.log("foo函数"this}
// 执行函数,并且强制 this 指向 obj 对象
foo.call(obj)

// 可以将 this 指定为 任意对象
foo.call("123")
foo.call(“abc”)


实现显式绑定的两个方法

function foo(name,age,height){
  console.log("foo函数被调用"this);
  console.log("打印参数",name,age,height);
}

apply()

语法:

foo.applay("apply",["shenqi",18,1.55]);
  • 第一个参数:this 所绑定的对象。例子中 this 绑定的对象为 ‘apply’这个字符串。
  • 第二个参数:额外的实参,需要以数组的形式传入
  • foo.applay(“apply”,[“shenqi”,18,1.55]);

call()

语法:

foo.call("call","shenqi",18,1.55);
  • 第一个参数:this 所绑定的对象。例子中 this 绑定的对象为 ‘call’这个字符串。
  • 参数列表:后续的参数以多参数的形式传递
  • foo.call(“call”,“shenqi”,18,1.55);

总结:第一个函数是相同的,参数均为this所需要指定的对象,后面的参数,apply为数组,call为参数列表.

bind()

我们发现 如果我们想多次调用指定好this指向的函数时都需要调用 apply或者 call。

 foo.applay(); 
 foo.applay(); 
 foo.applay(); 
 foo.applay(); 
 foo.applay(); 
 foo.applay(); 

有没有什么方法可以一劳永逸呢?
bind 便应运而生。
bind本质是 根据调用函数与指定的obj对象生成了一个新的函数,使得指定的obj 对象总绑定在 新的函数上。
独立函数的优先级低的,所以一定是 先执行bind方法绑定之后独立函数才会被执行

var bar = foo.bind()
bar()
bar()
bar()
bar()
bar()

bind方法创建的新的绑定函数(EF)是一个怪异函数对象

new绑定

JavaScript 中的函数可以当做一个类的构造函数来使用,也就是new关键字。
new 之后发生了什么?

  • 创建新的空对象F。
  • 将this指向这个空对象。
  • 指向函数体中的代码。
  • 没有显式返回非空对象时,默认返回这个对象。
function foo(){
  this.name = "shenqi"
  console.log("foo函数",this// 此时this 就是指向 默认创建的 全新的空对象 
}
new foo()

内置函数的绑定思考

有时候,我们会调用一些JavaScript的内置函数,或者一些第三方库中的内置函数。

  • 这些内置函数会要求我们传入另一个函数
  • 我们自己并不会显式了调用这些函数,都是当事件被触发后JS内部或者第三方库内部帮我们执行;
  • 这些函数中的this又是如果绑定的呢?

需要依靠
image.png

绑定优先级

  1. 默认绑定的优先级最低
  2. 显式绑定的优先级高于隐式绑定

image.png
this 指向:“abc”
在这里插入图片描述

this 指向 :“aaa”

  1. bind 的优先级高于 apply、call

image.png
this指向:“aaa”

  1. new绑定的优先级高于隐式绑定

image.png
this指向:一个空对象 和 false

  1. new绑定的优先级高于bind

在这里插入图片描述
this指向:一个空对象

  1. new和 call、apply是不允许一起使用的,没有可比性。

总结:new>bind>call=apply>默认绑定。
注意:new和 call、apply是不允许一起使用的,没有可比性。

完结散花

ok以上就是对 JS高级篇 |彻底搞清this指向问题 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。

参考文献

coderwhy老师JS高级视频教程

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:05:12  更:2022-09-13 11:08:58 
 
开发: 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 9:38:50-

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