JS: this point

Enjoy 2021-05-03 18:21:04
js point


this

One . this Point to

  • In the vast majority of cases , The way the function is called determines this Value ( Runtime binding ).

  • this Cannot be assigned during execution , And every time a function is called this The value of may also be different .

  • ES5 Introduced bind Method to set the this value , Regardless of how the function is called .

  • ES2015 Introduced Arrow function , The arrow function does not provide its own this binding (this The value of will remain the value of the closed lexical context ).

this Point to the who

  • Current execution context (global、function or eval) A property of , In a non-strict mode , Always point to an object , In strict mode, it can be any value .

Two . Global context

  • Whether or not in strict mode , In the global execution environment ( Outside any function body )this Both point to global objects .

  • // In the browser , window Objects are also global objects :
    console.log(this === window); // true
     Copy code 
  • have access to globalThis Get global objects , Whether or not the code executes in the current context .

3、 ... and . Function context

  • Inside the function ,this Depends on how the function is called

1. Nonstrict mode

  • Because the following code is not in strict mode , And this The value of is not set by the call , therefore this The value of points to global objects by default

  •  function f1() {
    return this;
    }
    // In the browser , The global object is window
    console.log(f1() === window); // true
    // stay Node in :
    console.log(f1() === globalThis);// true
    // adopt window call ,this Point to the window object
    console.log(window.f1() === window);// true
     Copy code 
  • // this Point to the obj object
    let obj = {
    a: 10,
    f1: function() {
    return this.a;
    },
    };
    console.log(obj.f1()); // 10
     Copy code 

2. Strict mode

  • In strict mode , If it is not set when entering the execution environment this Value ,this Will remain as undefined

  • function f2(){
    "use strict"; // Here's the strict pattern
    return this;
    }
    console.log(f2()); // undefined
    console.log(window.f2());// Print window object
     Copy code 

Four . Class context

  • this stay class The behavior in is similar to that in functions , Because a class is essentially a function , But there are also some differences and considerations .

  • In the constructor of a class ,this It's a regular object . All non static methods in the class are added to this In the prototype of

  • Static methods are not this Properties of , They are just properties of the class itself .

  • class Example {
    constructor() {
    // Object.getPrototypeOf(obj), This method takes an object as a parameter , And return the prototype of the object
    const proto = Object.getPrototypeOf(this);
    // Object.getOwnPropertyNames(obj) Method returns the property name of all its own properties of the specified object ( Include non enumerable properties but not Symbol Value as a property of name ) Array of components .
    console.log(Object.getOwnPropertyNames(proto));
    }
    first(){}
    second(){}
    static third(){}
    }
    new Example(); // ['constructor', 'first', 'second']
     Copy code 

Derived class

Derived classes use this
  • The constructor of a derived class has no initial this binding . Call in constructor super() Will generate a this binding , And it's equivalent to executing the following code ,Base Base class :

  • this = new Base();
     Copy code 
  • Calling super() Before quoting this Will throw an error .

Derived class returns
  • Derived classes cannot call super() Back before , Unless the constructor returns an object , Or no constructor at all

  • class Base {}
    class Good extends Base {}
    class AlsoGood extends Base {
    constructor() {
    return { a: 5 };
    }
    }
    class Bad extends Base {
    constructor() {}
    }
    console.log(new Good()); // good
    console.log(new AlsoGood()); // {a:5}
    console.log(new Bad());// ReferenceError
     Copy code 
  • class Bad extends Base {
    constructor() {
    super()
    }
    }
    console.log(new Bad());// Bad()
     Copy code 

5、 ... and . this And object transformation

1. call() Method

  • call(obj,arguments)

  • The first parameter is to add its own this Assigned to the function or object that calls the method this

  • The following parameters are the parameters of the calling function itself

  • function add(c=2, d=3) { return this.a + this.b + c + d;}var o = { a: 1, b: 3 };console.log(add.call(o,20,30))// 54
     Copy code 

2. apply() Method

  • And call() The method is similar to , It's just that the following parameters are presented as arrays

  • console.log(add.apply(o,[10,30]))// 44
     Copy code 
Non strict mode
  • Use in non strict mode call and apply when , If used as this The value of is not an object , Will be converted to an object .

  • null and undefined Is converted to a global object .

  • Original values such as 7 or 'foo' Will be converted to an object using the corresponding constructor .

  • console.log(add.apply(null))// NaN// this Will be converted into window, because window.a=undefined, therefore undefined+undefined+2+3=NaN // If set in advance window.a and window.b You can print it out
     Copy code 
  • console.log(add.apply(7))// NaN// this Will be converted into new Number(7), because Number.a=undefined, therefore undefined+undefined+2+3=NaN// If it is return this+c+d, You can print it out
     Copy code 

3. bind Method

  • ECMAScript 5 Introduced Function.prototype.bind(). call f.bind(someObject) Will create a f Functions with the same body and scope .

  • Be careful : But in this new function ,this Will be permanently bound to bind The first parameter of , No matter how the function is called .

  • Be careful : bind It only works once

  • function f(){ return this.a;}var g = f.bind({a:"azerty"});// The body of the function g Of this Has been permanently bound to {a: "azerty"} This object , Subsequent binding this There will be no change console.log(g()); // azertyvar h = g.bind({a:'yoo'}); // The body of the function g Of this Has been permanently bound to {a: "azerty"} This object ,h Of this Conversion does not work , A fellow g Function body this!console.log(h()); // azertyvar t = f.bind({a:'yoo'}); // The body of the function f No other functions have been called bind Method ,this Can be dynamically transformed , Can be called multiple times bind Method to create the same function body and transformation this!console.log(t()); // yoovar o = {a:37, f:f, g:g, h:h,t:t};console.log(o.a, o.f(), o.g(), o.h(),o.t()); // 37, 37, azerty, azerty,yoo
     Copy code 

6、 ... and . Arrow function

Global object
  • stay Arrow function in ,this With a closed lexical environment this bring into correspondence with . In the global code , It will be set as a global object :

  • var globalObject = this; var foo = () => this; let obj = { a: 2, arrowFun: foo, }; function test() { let obj1 = obj; return obj1.arrowFun(); } console.log(foo() === globalObject); // true console.log(obj.fun() === globalObject); // true console.log(test() === globalObject);// true, Function calls itself , Its this The default is window object
     Copy code 
  • If you will this Pass to callbind、 perhaps apply To call the arrow function , It will be ignored . But you can still add parameters to the call , But the first parameter (thisArg) It should be set to null.

  • // Try to use call To set thisconsole.log(foo.call(obj) === globalObject); // true, because this The transfer failed // Try to use bind To set thisfoo = foo.bind(obj);console.log(foo() === globalObject); // true, because this The transfer failed
     Copy code 
  • in any case ,foo Of this Is set to the environment in which it was created ( In the example above , It's the global object ).

Local objects
  • The same applies to arrow functions created within other functions : These arrow functions are this Set as a closed lexical environment .

  • // bar Returns a function ,// This function returns this,// The returned function is created with the arrow function ,// So it's this Is permanently bound to its outer function this.// It's the outer layer of the anonymous function this Point to obj// bar The value of can be set in the call , This in turn sets the value of the return function .var obj = { bar: function() { var x = (() => this); return x; }};// As obj Object to call bar, It's this Bound to the obj.var fn = obj.bar();// So return the function's this Point to objconsole.log(fn() === obj); // true// But notice , If you just quote obj Methods ,// Instead of calling it var fn2 = obj.bar; // At this time fn2=function() { // var x = (() => this); // return x; // } // That's right this Bound to its outer function this, The outer function is not called to execute ,this The default point to window// So after calling the arrow function ,this Point to window. console.log(fn2()() == window); // true // fn2()=()=>this // fn2()()==window
     Copy code 

7、 ... and . Method as object

  • When a function is called as a method in an object , Of this function this The object set to call the function .

  • var o = { prop: 37, f: function() { return this.prop; }};console.log(o.f()); // 37
     Copy code 
  • This behavior is completely unaffected by how or where the function is defined

  • We can also define functions first , And then attach it to o.f.

  • var o = {prop: 37};function independent() { return this.prop;}o.f = independent;console.log(o.f()); // 37
     Copy code 
  • this The binding of is only affected by the closest member reference .

  • o.b = {g: independent, prop: 42};console.log(o.b.g()); // 42
     Copy code 

8、 ... and . In the prototype chain **this**

  • If the method exists on the prototype chain of an object , that this Point to the object that calls this method , Just as the method is on this object .

  • var o = { f: function() { return this.a + this.b; }};var p = Object.create(o);p.a = 1;p.b = 4;console.log(p.f()); // 5
     Copy code 
  • object p There is nothing of its own f attribute , its f Property is inherited from its prototype . Although in the end o Find f Attribute , It doesn't matter ;

  • because f As a p Of the method called , So it's this Yes p

Nine . getter And setter Medium this

  • Used as a getter or setter All of these functions will put this Bound to an object that sets or gets properties .

  • function sum() { return this.a + this.b + this.c;}var o = { a: 1, b: 2, c: 3, get average() { return Math.ceil((this.a + this.b + this.c) / 3); }};Object.defineProperty(o, 'sum', { get: sum, enumerable: true, configurable: true});console.log(o.average, o.sum); // 2, 6
     Copy code 

Ten . As constructor

  • When a function is used as a constructor ( Use new keyword ), its this Is bound to the new object being constructed .

  • /* * This is how constructors work : * * function MyConstructor(){ * // Function entities are written here * // On demand this Create properties on , And then assign values to them , such as : * this.fum = "nom"; * // wait ... * * // If the function has a return sentence , * // Then the object will be new Result of expression . * // otherwise , The result of the expression is that it is currently bound to this The object of . * //( That is, the common situation we usually see ). * } */function C(){ this.a = 37;}var o = new C();console.log(o.a); // Constructors C Of this Is bound to the new object being constructed O On ,37function C2(){ this.a = 37; return {a:38};}o = new C2();console.log(o.a); // Constructors C Return an object , And assign the object to the new object being constructed O,38function C3(){ this.a = 37; return 123;}o = new C3();console.log(o.a); // Constructors C There is a return , But not an object , The result is like the first way ,37
     Copy code 

11、 ... and . As a DOM Event handler

  • When a function is used as an event handler , its this Points to the element that triggered the event ( Some browsers are using non addEventListener Does not adhere to this Convention when the listener function is dynamically added by the function of ).

  • // When called , Turn the associated elements blue function bluify(e){ console.log(this === e.currentTarget); // Always true // When currentTarget and target Is the same object true console.log(this === e.target); this.style.backgroundColor = '#A5D9F3';}// Get a list of all the elements in the document var elements = document.getElementsByTagName('*');// take bluify Click listener functions as elements , When the element is clicked , It turns blue , Using event bubbling for(var i=0 ; i<elements.length ; i++){ elements[i].addEventListener('click', bluify, false);}
     Copy code 

Twelve . As an inline event handler

  • When code is inlined on-event Processing function Invocation time , its this Point to where the monitor is DOM Elements :

  • <button onclick="alert(this.tagName.toLowerCase());"> Show this</button>
     Copy code 
  • above alert Will be displayed button. Note that only in the outer code this It's set up like this :

  • <button onclick="alert((function(){return this})());"> Show inner this</button>
     Copy code 
  • under these circumstances , There is no internal function set this, So it points to global/window object ( That is, the function called in non strict mode is not set this The default object to point to when , In strict mode undefined).

Twelve . Class this

  • class Car { constructor() { // take sayBye Methodical this Always bind to Car Of this this.sayBye = this.sayBye.bind(this); } sayHi() { console.log(`Hello from ${this.name}`); } sayBye() { console.log(`Bye from ${this.name}`); } get name() { return 'Ferrari'; }}class Bird { get name() { return 'Tweety'; }}const car = new Car();const bird = new Bird();car.sayHi(); // Hello from Ferraribird.sayHi = car.sayHi; // quote car But did not call , In the method this By default, it points to the object calling the method bird.sayHi(); // Hello from Tweety// because Car Of sayBye Methodical this Always bind to Car Of this, Even if the reference does not call ,this The value of can't be changed any more bird.sayBye = car.sayBye;bird.sayBye(); // Bye from Ferrari
     Copy code 
版权声明
本文为[Enjoy]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/05/20210503181828329v.html

  1. 浅谈 React 中的 XSS 攻击
  2. XSS attack in react
  3. 自学前端教程整理,附不容错过的前端100篇文章合集
  4. Self taught front-end tutorial collation, with a collection of 100 front-end articles that can not be missed
  5. 使用OpenTracing跟踪Go中的HTTP请求延迟
  6. Using opentracing to track HTTP request latency in go
  7. Encapsulating databinding allows you to write less than 10000 lines of code
  8. 03-HTML5标签-HTML5极速入门
  9. 03-html5 tag-html5 quick start
  10. LayUI - 极易上手拿来即用的前端 UI 框架
  11. Layui - easy to use front end UI framework
  12. Interpretation of lodash source code (1)
  13. Why is the first parameter of node family callback error?
  14. 报告:JavaScript 开发者达1380 万,C#超越 PHP,Rust 增长最快
  15. Report: Javascript developers reach 13.8 million, C surpasses PHP, and rust grows fastest
  16. 小白前端入门笔记(10),怎么设置网站内部的超链接?
  17. How to set up hyperlinks inside the website?
  18. Using node and socket to realize online chat room
  19. The core competitiveness of Vue: data bidirectional binding
  20. React configuration agent
  21. CSS layout
  22. Application scenario explanation of Vue dynamic component
  23. Redux learning notes 04 -- using multiple reducers to manage data
  24. After three months of typescript writing, what have I learned?
  25. Node family - what is a callback?
  26. React -- a simple implementation of render & create element
  27. JS learning simple usage of jquery
  28. Seamless love
  29. 小白前端入门笔记(12),设置哑链接
  30. Small white front-end entry notes (12), set dumb links
  31. Vue2. X opens composition API and TSX
  32. Interview record and thinking of social recruitment for one and a half years (Alibaba, Tencent, baidu offer)
  33. Flex learning notes
  34. The most essential closure article in the eastern hemisphere
  35. 2021-05-03 hot news
  36. Sword finger offer -- reverse order pair in array (JS Implementation)
  37. Working process of scaffold
  38. Use decorator mode to strengthen your fetch
  39. [JS] scope (Introduction)
  40. Employment information statistics network (interface document)
  41. Analysis of MVC
  42. [middle stage] please stay and join me in the backstage
  43. Understanding front end garbage collection
  44. [continuous update] front end special style implementation
  45. Flutter product analysis and package reduction scheme
  46. XPath positioning
  47. 前端开发css中的flex布局的使用
  48. The use of flex layout in front end development CSS
  49. JQuery核心函数和静态方法
  50. JQuery core functions and static methods
  51. Node family - understanding of blocking and non blocking
  52. 热点微前端Microfrontend的讨论:谷歌AdWords是真实的微前端
  53. Vue source code analysis (2) initproxy initialization proxy
  54. What's TM called react diff
  55. Summary of common front end data structure
  56. Useeffect in hooks
  57. [encapsulation 02 design pattern] Command pattern, share meta pattern, combination pattern, proxy pattern, strategy pattern
  58. Front end notes: virtual Dom and diff of vue2. X
  59. The best code scanning plug-in of flutter
  60. The simplest plug-in for rights management of flutter