An article that understands this point and catches up with 70% of front-end people
Colleagues got stuck because of the problem pointed by thisbug
, vue2’s this pointed problem
, using the arrow function, resulting in the inability to get the corresponding props
. He didn't know it when I introduced it to him, and then I deliberately looked at the front-end communication group. So far, at least 70% of front-end programmers still don't understand it. I'll share it with you today this
Point, if you haven’t learned anything, please give me a big mouth.
1. Calling location
- The scope is related to where it is defined and has nothing to do with where it is executed
-
this
The pointer has nothing to do with where it is defined, it has to do with how it is called and in what form -
this
(this) how this function is called (convenient to remember) - In order to facilitate understanding, strict mode is not enabled by default
2. Binding rules
We introduced above,this
Pointing mainly depends on the form of calling. Next, I will introduce the calling rules to you. Without rules, nothing is complete. Just keep these calling rules in mind. There is nothing difficult.
- You must find the calling location, and then determine which of the following four binding rules is
- Secondly, you must also know the priority of these four binding rules.
- You know these two points and it will be easy for you to know where this points.
2.1 Default binding
Functions are the most commonly used The calling method, the type of calling function: independent function call
function bar() { console.log(this) // window }
- bar is a direct call without any modifier, so the default binding is
window
- In strict mode,
this
here isundefined
##2.2 Implicit binding
Use the most In layman's terms, it means: the object has a certain method, and the method is accessed through this object and called directly (note: the arrow function is special, which will be explained below)const info = { fullName: 'ice', getName: function() { console.log(this.fullName) } } info.getName() // 'ice'
- This function is
- info
The call is initiated and implicit binding is performed, so the current
thisis
info, and the value accessed through
this.fullNameis undoubtedly
ice
Implicit loss normal
In some cases, implicit loss will be performed, and the implicitly bound function will lose the bound object. , that is to say, it becomes the default binding. Thethis value of the default binding is
window or
undefined, depending on the environment you are currently in. Whether it is strict mode.
const info = { fullName: 'ice', getName: function() { console.log(this.fullName) } } const fn = info.getName fn() //undefinedIn this case, implicit loss is performed and the bound object is lost. Why does such a problem occur? If you are familiar with memory, it will be easy to understand.
- There is no direct call here, but the memory address corresponding to
- getName
is found through
infoand assigned to the variable
fn Then the call was made directly through - fn
- window
, from
windowTake out the
fullNameattribute, which must be
undefined
Implicit loss advancedWhat do you need to understand first? Is the callback function. In fact, it can be understood this way, that is, I don't call it now, but pass it to other places in the form of parameters, and call it somewhere else.
//申明变量关键字必须为var var fullName = 'panpan' const info = { fullName: 'ice', getName: function() { console.log(this.fullName) } } function bar(fn) { //fn = info.getName fn() // panpan } bar(info.getName)
- First of all,
- fn
in
baris a callback function
- fn = info.getName
parameter passing It is an implicit assignment. In fact, it has the same meaning as the implicit loss above. They all point to
fn = info.getNamereferences, which is their memory addresses
because they The - this
is lost, that is, the function is called independently, the default binding rule is,
thisis the global
windowobject
Note: Why must the declaration be What about - var
?
- Because only the variables declared by
- var
will be added to the global
windowobject
If - let\const
is used, then No, I will introduce the two keywords for declaring variables in detail
But in some scenarios, I don’t want implicit loss. What should I do? Let’s introduce display binding to you. , that is, fixed call. - var
2.3 Display binding
However, in some scenarios, the changes inthis are unexpected. In fact, we There is no control over how the callback function is executed, so there is no way to control that the calling location has the expected binding that this points to.
2.3.1 call/apply/bind
“All” functions in js have some useful features. This is related to its prototype chain. Follow-up I will introduce in the prototype, the method of implementing inheritance in disguise through the prototype chain js, among which the three methodscall/apply/bind are the methods on the function prototype chain, and they can be called in the function.
2.3.2 call
-
call()
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。- 第一个参数为固定绑定的
this
对象 - 第二个参数以及二以后的参数,都是作为参数进行传递给所调用的函数
- 第一个参数为固定绑定的
- 备注
- 该方法的语法和作用与
apply()
方法类似,只有一个区别,就是call()
方法接受的是一个参数列表,而apply()
方法接受的是一个包含多个参数的数组。
- 该方法的语法和作用与
var fullName = 'panpan' const info = { fullName: 'ice', getName: function(age, height) { console.log(this.fullName, age, height) } } function bar(fn) { fn.call(info, 20, 1.88) //ice 20 1.88 } bar(info.getName)
2.3.3 apply
- 与
call
的方法类似,只是参数列表有所不同- 参数
-
call
参数为单个传递 -
apply
参数为数组传递
-
- 参数
var fullName = 'panpan' const info = { fullName: 'ice', getName: function(age, height) { console.log(this.fullName, age, height) } } function bar(fn) { fn.apply(info, [20, 1.88]) //ice 20 1.88 } bar(info.getName)
2.3.4 bind
-
bind
与apply/call
之间有所不同,bind
传入this
,则是返回一个this
绑定后的函数,调用返回后的函数,就可以拿到期望的this。 - 参数传递则是
- 调用
bind
时,可以传入参数 - 调用
bind
返回的参数也可以进行传参
- 调用
var fullName = 'panpan' const info = { fullName: 'ice', getName: function(age, height) { console.log(this.fullName, age, height) //ice 20 1.88 } } function bar(fn) { let newFn = fn.bind(info, 20) newFn(1.88) } bar(info.getName)
2.4 new绑定
谈到new
关键字,就不得不谈构造函数,也就是JS中的 "类",后续原型篇章在跟大家继续探讨这个new关键字,首先要明白以下几点,new Fn()
的时候发生了什么,有利于我们理解this
的指向。
创建了一个空对象
将this指向所创建出来的对象
把这个对象的[[prototype]] 指向了构造函数的prototype属性
执行代码块代码
如果没有明确返回一个非空对象,那么返回的对象就是这个创建出来的对象
function Person(name, age) { this.name = name this.age = age } const p1 = new Person('ice', 20) console.log(p1) // {name:'ice', age:20}
- 当我调用
new Person()
的时候,那个this所指向的其实就是p1
对象
3. 绑定优先级
3.1 隐式绑定 > 默认绑定
function bar() { console.log(this) //info } const info = { bar: bar } info.bar()
- 虽然这边比较有些勉强,有些开发者会认为这是默认绑定的规则不能直接的显示谁的优先级高
- 但是从另外一个角度来看,隐式绑定,的this丢失以后this才会指向
widonw或者undefined
,变相的可以认为隐式绑定 > 默认绑定
3.2 显示绑定 > 隐式绑定
var fullName = 'global ice' const info = { fullName: 'ice', getName: function() { console.log(this.fullName) } } info.getName.call(this) //global ice info.getName.apply(this) //global ice info.getName.bind(this)() //global ice
- 通过隐式绑定和显示绑定的一起使用很明显 显示绑定 > 隐式绑定
3.3 bind(硬绑定) > apply/call
function bar() { console.log(this) //123 } const newFn = bar.bind(123) newFn.call(456)
3.4 new绑定 > bind绑定
首先我们来说一下,为什么是和bind
比较,而不能对call
和apply
比较,思考下面代码
const info = { height: 1.88 } function Person(name, age) { this.name = name this.age = age } const p1 = new Person.call('ice', 20) //报错: Uncaught TypeError: Person.call is not a constructor
new绑定和bind绑定比较
const info = { height: 1.88 } function Person(name, age) { this.name = name this.age = age } const hasBindPerson = Person.bind(info) const p1 = new hasBindPerson('ice', 20) console.log(info) //{height: 1.88}
- 我们通过
bind
对Person
进行了一次劫持,硬绑定了this为info
对象 -
new
返回的固定this的函数 - 但是我们发现 并不能干预this的指向
3.5 总结
new关键字
> bind
> apply/call
> 隐式绑定
> 默认绑定
4. 箭头函数 (arrow function)
首先箭头函数是ES6
新增的语法
const foo = () => {}
4.1 箭头函数this
var fullName = 'global ice' const info = { fullName: 'ice', getName: () => { console.log(this.fullName) } } info.getName() //global ice
- 你会神奇的发现? 为什么不是默认绑定,打印结果为
ice
- 其实这是
ES6
的新特性,箭头函数不绑定this
,它的this
是上一层作用域,上一层作用域为window
- 所以打印的结果是
global ice
4.2 箭头函数的应用场景 进阶
- 需求: 在
getObjName
通过this
拿到info
中的fullName
(值为ice
的fullName
)
const info = { fullName: 'ice', getName: function() { let _this = this return { fullName: 'panpan', getObjName: function() { console.log(this) // obj console.log(_this.fullName) } } } } const obj = info.getName() obj.getObjName()
当我调用
info.getName()
返回了一个新对象当我调用返回对象的
getObjName
方法时,我想拿到最外层的fullName
,我通过,getObjName
的this访问,拿到的this却是obj
,不是我想要的结果我需要在调用
info.getName()
把this保存下来,info.getName()
是通过隐式调用,所以它内部的this就是info对象getObjName
是obj对象,因为也是隐式绑定,this必定是obj对象,绕了一大圈我只是想拿到上层作用域的this而已,恰好箭头函数解决了这一问题
const info = { fullName: 'ice', getName: function() { return { fullName: 'panpan', getObjName: () => { console.log(this.fullName) } } } } const obj = info.getName() obj.getObjName()
5. 总结
5.1 this的四种绑定规则
默认绑定
隐式绑定
显示绑定 apply/call/bind(也称硬绑定)
new绑定
5.2 this的优先级 从高到低
new绑定
bind
call/apply
隐式绑定
默认绑定
6. 结语
当一切都看起来不起作用的时候,我就会像个石匠一样去敲打石头,可能敲100次,石头没有任何反应,但是101次,石头可能就会裂为两半 我知道并不是第101次起了作用,而是前面积累所致。
大家有疑惑可以在评论区留言 第一时间为大家解答。
(学习视频分享:web前端开发)

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 Chinese version
Chinese version, very easy to use

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver Mac version
Visual web development tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.