search
HomeWeb Front-endJS TutorialFour binding forms of this in javascript functions

Four binding forms of this in javascript functions

Feb 22, 2018 am 09:30 AM
javascriptjsthis

When it comes to this, many abstract concepts that make people dizzy come out. Here I will only talk about the core point - this in a function always points to the object that calls it. , the following stories will all revolve around this point.
[Story] There is a young man named "Dis" (this). One day, Dis accidentally traveled to a different world called "Gavaskeli" (javascript). At this moment, Dis Being penniless, the first thing he has to do is to find his place to stay - the object to call the function

default binding of this

[Story - Line 1] If Dis (this) is not available until dark Unable to find a place to take him in, he was about to live the life of an African refugee. At this time, a kind-hearted magician village chief - window savior appeared like a savior: Stay in my house first!

[Text]
When a function does not have a clear calling object, that is, when it is simply called as an independent function , the default binding will be used for this of the function: bound to the global window object
function fire () {
     console.log(this === window)
}
fire(); // 输出true

I believe the above example will be useful for everyone Most people are very simple, but sometimes it can be confusing if we change the example:
Four binding forms of this in javascript functions
function fire () {
  // 我是被定义在函数内部的函数哦!     function innerFire() {
  console.log(this === window)
      }
     innerFire(); // 独立函数调用}
fire(); // 输出true
Four binding forms of this in javascript functions

The function innerFire is declared and called in an external function fire, so who does its this point to? Still window
Many people may be concerned about the impact of the scope of the fire function on innerFire, but we only need to seize our theoretical weapon-when there is no clear calling object, we will use this of the function Default binding: Bind to the global window object to get the correct answer
The enhanced version of the example below also outputs true
Four binding forms of this in javascript functions
var obj = {
   fire: function () {
       function innerFire() {
          console.log(this === window)
        }
        innerFire();   // 独立函数调用     }
}
obj.fire(); //输出 true
Four binding forms of this in javascript functions

[Note] In this example, obj The call to .fire() actually uses the implicit binding of this. This is what I will talk about below. I will continue to explain this example next.
[Summary] Everything function is called as an independent function , no matter where it is, its behavior is the same as calling it directly in the global environment

The hidden meaning of this Type binding

[Story - Route 2] When Dis (this) traveled to the different world "Gavaskeli" (javascript), he happened to have some money with him, so he found a hotel to stay. Come down

When a function is "contained" by an object, we say that the this of the function is implicitly bound to the object. This At this time, you can directly access other properties in the bound object through this, such as the following a property
Four binding forms of this in javascript functions##
var obj = {
     a: 1,
      fire: function () {
           console.log(this.a)
        }
}
obj.fire(); // 输出1
Four binding forms of this in javascript functions

Now we need to do some deeper thinking about the common code operations. First, the following two paragraphs The effect achieved by the code is the same:
Four binding forms of this in javascript functions
// 我是第一段代码function fire () {
      console.log(this.a)
}
  var obj = {
      a: 1,
      fire: fire
  }
obj.fire(); // 输出1
 // 我是第二段代码var obj = {
        a: 1,
        fire: function () {
             console.log(this.a)
         }
}
obj.fire(); // 输出1
Four binding forms of this in javascript functions

The fire function does not make any difference because it is defined inside and outside the obj object. That is to say, in the above two forms of implicit binding, fire The a property in obj can still be accessed through this, which tells us:
1. This is dynamically bound, or it is bound during the code running period rather than during the writing period
2. The independence of functions from objects, the problem of loss of this transmission
 
(下面的描述可能带有个人的情感倾向而显得不太严谨,但这是因为我希望阅读者尽可能地理解我想表达的意思)
Four binding forms of this in javascript functions

隐式绑定下,作为对象属性的函数,对于对象来说是独立的

 
基于this动态绑定的特点,写在对象内部,作为对象属性的函数,对于这个对象来说是独立的。(函数并不被这个外部对象所“完全拥有”)
 
我想表达的意思是:在上文中,函数虽然被定义在对象的内部中,但它和“在对象外部声明函数,然后在对象内部通过属性名称的方式取得函数的引用”,这两种方式在性质上是等价的(而不仅仅是效果上)
 
定义在对象内部的函数只是“恰好可以被这个对象调用”而已,而不是“生来就是为这个对象所调用的”
 
借用下面的隐式绑定中的this传递丢失问题来说明:
Four binding forms of this in javascript functions
var obj = {
      a: 1,    // a是定义在对象obj中的属性   1      fire: function () {
   console.log(this.a)
        }
      }
 var a = 2;  // a是定义在全局环境中的变量    2var fireInGrobal = obj.fire;  
fireInGrobal(); //  输出 2
Four binding forms of this in javascript functions

 

 
上面这段简单代码的有趣之处在于: 这个于obj中的fire函数的引用( fireInGrobal)在调用的时候,行为表现(输出)完全看不出来它就是在obj内部定义的,其原因在于:我们隐式绑定的this丢失了!! 从而 fireInGrobal调用的时候取得的this不是obj,而是window
 
上面的例子稍微变个形式就会变成一个可能困扰我们的bug:
 
Four binding forms of this in javascript functions
var a = 2;var obj = {
    a: 1,    // a是定义在对象obj中的属性    fire: function () {
          console.log(this.a)
     }
}  
function otherFire (fn) {
     fn();
}  
otherFire(obj.fire); // 输出2
Four binding forms of this in javascript functions

 

 
在上面,我们的关键角色是otherFire函数,它接受一个函数引用作为参数,然后在内部直接调用,但它做的假设是参数fn仍然能够通过this去取得obj内部的a属性,但实际上, this对obj的绑定早已经丢失了,所以输出的是全局的a的值(2),而不是obj内部的a的值(1)
 Four binding forms of this in javascript functions

在一串对象属性链中,this绑定的是最内层的对象

在隐式绑定中,如果函数调用位置是在一串对象属性链中,this绑定的是最内层的对象。如下所示:
Four binding forms of this in javascript functions
var obj = {
      a: 1,
      obj2: {
           a: 2,
           obj3: {
                a:3,
                getA: function () {
                    console.log(this.a)   
                 }
           }
       }
}
 
obj.obj2.obj3.getA();  // 输出3
Four binding forms of this in javascript functions

 

this的显式绑定:(call和bind方法)

【故事——线路3】 迪斯(this)穿越来异世界“伽瓦斯克利”(javascript),经过努力的打拼,积累了一定的财富,于是他买下了自己的房子
 

 

上面我们提到了this的隐式绑定所存在的this绑定丢失的问题,也就是对于 “ fireInGrobal = obj.fire”
fireInGrobal调用和obj.fire调用的结果是不同的,因为这个函数赋值的过程无法把fire所绑定的this也传递过去。这个时候,call函数就派上用场了

 

call的基本使用方式: fn.call(object)
fn是你调用的函数,object参数是你希望函数的this所绑定的对象。
fn.call(object)的作用:
1.即刻调用这个函数(fn)
2.调用这个函数的时候函数的this指向object对象
 
例子:
Four binding forms of this in javascript functions
var obj = {
      a: 1,    // a是定义在对象obj中的属性      fire: function () {
         console.log(this.a)
      }
}
 var a = 2;  // a是定义在全局环境中的变量  var fireInGrobal = obj.fire;
fireInGrobal();   // 输出2fireInGrobal.call(obj); // 输出1
Four binding forms of this in javascript functions

 

 
原本丢失了与obj绑定的this参数的fireInGrobal再次重新把this绑回到了obj
 
但是,我们其实不太喜欢这种每次调用都要依赖call的方式,我们更希望:能够一次性 返回一个this被永久绑定到obj的fireInGrobal函数,这样我们就不必每次调用fireInGrobal都要在尾巴上加上call那么麻烦了。
 
怎么办呢? 聪明的你一定能想到,在fireInGrobal.call(obj)外面包装一个函数不就可以了嘛!
Four binding forms of this in javascript functions
var obj = {
      a: 1,    // a是定义在对象obj中的属性      fire: function () {
        console.log(this.a)
      }
}
 var a = 2;  // a是定义在全局环境中的变量  var fn = obj.fire;var fireInGrobal = function () {
    fn.call(obj)   //硬绑定}
       
fireInGrobal(); // 输出1
Four binding forms of this in javascript functions

 

如果使用bind的话会更加简单
var fireInGrobal = function () {
    fn.call(obj)   //硬绑定}

 

可以简化为:
var fireInGrobal = fn.bind(obj);

 

call和bind的区别是:在绑定this到对象参数的同时:
 
1.call将立即执行该函数
2.bind不执行函数,只返回一个可供执行的函数
 
【其他】:至于apply,因为除了使用方法,它和call并没有太大差别,这里不加赘述
 
在这里,我把显式绑定和隐式绑定下,函数和“包含”函数的对象间的关系比作买房和租房的区别。
 

 

因为this的缘故
 
在隐式绑定下:函数和只是暂时住在“包含对象“的旅馆里面,可能过几天就又到另一家旅馆住了
在显式绑定下:函数将取得在“包含对象“里的永久居住权,一直都会”住在这里“
 

new绑定

【故事】 迪斯(this)组建了自己的家庭,并生下多个孩子(通过构造函数new了许多个对象)
 
 

 

执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象
 
Four binding forms of this in javascript functions
function foo (a) {     this.a = a;
}
 var a1  = new foo (1);var a2  = new foo (2);var a3  = new foo (3);var a4  = new foo (4);
 
console.log(a1.a); // 输出1console.log(a2.a); // 输出2console.log(a3.a); // 输出3console.log(a4.a); // 输出4

相关推荐:

JavaScript中的this规则及this对象用法实例

函数调用的不同方式及this的指向详解

js中this对象用法实例详解

The above is the detailed content of Four binding forms of this in javascript functions. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
The Relationship Between JavaScript, C  , and BrowsersThe Relationship Between JavaScript, C , and BrowsersMay 01, 2025 am 12:06 AM

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js Streams with TypeScriptNode.js Streams with TypeScriptApr 30, 2025 am 08:22 AM

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

Python vs. JavaScript: Performance and Efficiency ConsiderationsPython vs. JavaScript: Performance and Efficiency ConsiderationsApr 30, 2025 am 12:08 AM

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

The Origins of JavaScript: Exploring Its Implementation LanguageThe Origins of JavaScript: Exploring Its Implementation LanguageApr 29, 2025 am 12:51 AM

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

Behind the Scenes: What Language Powers JavaScript?Behind the Scenes: What Language Powers JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.

The Future of Python and JavaScript: Trends and PredictionsThe Future of Python and JavaScript: Trends and PredictionsApr 27, 2025 am 12:21 AM

The future trends of Python and JavaScript include: 1. Python will consolidate its position in the fields of scientific computing and AI, 2. JavaScript will promote the development of web technology, 3. Cross-platform development will become a hot topic, and 4. Performance optimization will be the focus. Both will continue to expand application scenarios in their respective fields and make more breakthroughs in performance.

Python vs. JavaScript: Development Environments and ToolsPython vs. JavaScript: Development Environments and ToolsApr 26, 2025 am 12:09 AM

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

Is JavaScript Written in C? Examining the EvidenceIs JavaScript Written in C? Examining the EvidenceApr 25, 2025 am 12:15 AM

Yes, the engine core of JavaScript is written in C. 1) The C language provides efficient performance and underlying control, which is suitable for the development of JavaScript engine. 2) Taking the V8 engine as an example, its core is written in C, combining the efficiency and object-oriented characteristics of C. 3) The working principle of the JavaScript engine includes parsing, compiling and execution, and the C language plays a key role in these processes.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor