cari

Rumah  >  Soal Jawab  >  teks badan

Fahami fungsi dan penggunaan kata kunci "ini" yang sesuai

Saya berharap dapat mencari penjelasan yang jelas tentang perkara yang dilakukan oleh kata kunci "ini" dan cara menggunakannya dengan betul.

Nampaknya berkelakuan pelik dan saya tidak faham sepenuhnya mengapa.

thisBagaimana ia berfungsi dan bila anda perlu menggunakannya?

P粉155551728P粉155551728473 hari yang lalu614

membalas semua(2)saya akan balas

  • P粉087951442

    P粉0879514422023-10-13 14:03:41

    Berbanding dengan bahasa lain, this 关键字在 JavaScript 中的行为有所不同。在面向对象语言中,this 关键字指的是该类的当前实例。在 JavaScript 中,this 的值由函数的调用上下文 (context.function()) dan kedudukan panggilannya ditentukan.

    <强>1. Apabila digunakan dalam konteks global

    Apabila anda menggunakannya dalam konteks global this 时,它会绑定到全局对象(浏览器中的window)

    document.write(this);  //[object Window]

    Apabila anda menggunakan this 时,this di dalam fungsi yang ditakrifkan dalam konteks global anda masih terikat dengan objek global kerana fungsi itu sebenarnya adalah kaedah konteks global. < /p>

    function f1()
    {
       return this;
    }
    document.write(f1());  //[object Window]

    Panggil pada objek f1是一个全局对象的方法。因此我们也可以在 window di atas, seperti ini:

    function f()
    {
        return this;
    }
    
    document.write(window.f()); //[object Window]

    <强>2. Apabila digunakan di dalam kaedah objek

    Apabila anda menggunakan this 关键字时,this di dalam kaedah objek ia mengikat objek "terus" yang melampirkan.

    var obj = {
        name: "obj",
        f: function () {
            return this + ":" + this.name;
        }
    };
    document.write(obj.f());  //[object Object]:obj

    Saya telah meletakkan perkataan "segera" dalam petikan berganda di atas. Ini adalah untuk menunjukkan bahawa jika objek bersarang dalam objek lain, this terikat pada objek induk terdekat.

    var obj = {
        name: "obj1",
        nestedobj: {
            name:"nestedobj",
            f: function () {
                return this + ":" + this.name;
            }
        }            
    }
    
    document.write(obj.nestedobj.f()); //[object Object]:nestedobj

    Walaupun anda menambah fungsi sebagai kaedah pada objek secara eksplisit, ia masih mengikut peraturan di atas, iaitu this masih menunjuk kepada objek induk langsung.

    var obj1 = {
        name: "obj1",
    }
    
    function returnName() {
        return this + ":" + this.name;
    }
    
    obj1.f = returnName; //add method to object
    document.write(obj1.f()); //[object Object]:obj1

    <强>3. Apabila memanggil fungsi tanpa konteks

    Digunakan this 时,它会绑定到全局对象(浏览器中的window) apabila anda memanggilnya di dalam fungsi tanpa sebarang konteks (iaitu bukan pada sebarang objek) (walaupun jika fungsi itu ditakrifkan di dalam objek).

    var context = "global";
    
    var obj = {  
        context: "object",
        method: function () {                  
            function f() {
                var context = "function";
                return this + ":" +this.context; 
            };
            return f(); //invoked without context
        }
    };
    
    document.write(obj.method()); //[object Window]:global

    Cuba semua dengan fungsi

    Kita juga boleh menggunakan fungsi untuk mencuba perkara di atas. Tetapi masih terdapat beberapa perbezaan.

    • Di atas kami menambah ahli pada objek menggunakan notasi literal objek. Kita boleh menambah ahli ke fungsi menggunakan this. untuk menentukan mereka.
    • Notasi literal objek mencipta contoh objek yang boleh kami gunakan serta-merta. Untuk fungsi, kita mungkin perlu mencipta instance menggunakan operator new dahulu.
    • Juga dalam kaedah literal objek, kita boleh menambah ahli secara eksplisit pada objek yang ditentukan menggunakan pengendali titik. Ini hanya ditambahkan pada keadaan tertentu. Walau bagaimanapun, saya telah menambah pembolehubah pada prototaip fungsi supaya ia ditunjukkan dalam semua keadaan fungsi.

    Di bawah saya mencuba semua yang saya lakukan di atas dengan Object dan this tetapi mula-mula mencipta fungsi dan bukannya menulis objek secara langsung.

    /********************************************************************* 
      1. When you add variable to the function using this keyword, it 
         gets added to the function prototype, thus allowing all function 
         instances to have their own copy of the variables added.
    *********************************************************************/
    function functionDef()
    {
        this.name = "ObjDefinition";
        this.getName = function(){                
            return this+":"+this.name;
        }
    }        
    
    obj1 = new functionDef();
    document.write(obj1.getName() + "
    "); //[object Object]:ObjDefinition /********************************************************************* 2. Members explicitly added to the function protorype also behave as above: all function instances have their own copy of the variable added. *********************************************************************/ functionDef.prototype.version = 1; functionDef.prototype.getVersion = function(){ return "v"+this.version; //see how this.version refers to the //version variable added through //prototype } document.write(obj1.getVersion() + "
    "); //v1 /********************************************************************* 3. Illustrating that the function variables added by both above ways have their own copies across function instances *********************************************************************/ functionDef.prototype.incrementVersion = function(){ this.version = this.version + 1; } var obj2 = new functionDef(); document.write(obj2.getVersion() + "
    "); //v1 obj2.incrementVersion(); //incrementing version in obj2 //does not affect obj1 version document.write(obj2.getVersion() + "
    "); //v2 document.write(obj1.getVersion() + "
    "); //v1 /********************************************************************* 4. `this` keyword refers to the immediate parent object. If you nest the object through function prototype, then `this` inside object refers to the nested object not the function instance *********************************************************************/ functionDef.prototype.nestedObj = { name: 'nestedObj', getName1 : function(){ return this+":"+this.name; } }; document.write(obj2.nestedObj.getName1() + "
    "); //[object Object]:nestedObj /********************************************************************* 5. If the method is on an object's prototype chain, `this` refers to the object the method was called on, as if the method was on the object. *********************************************************************/ var ProtoObj = { fun: function () { return this.a } }; var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj //as its prototype obj3.a = 999; //adding instance member to obj3 document.write(obj3.fun()+"
    ");//999 //calling obj3.fun() makes //ProtoObj.fun() to access obj3.a as //if fun() is defined on obj3

    <强>4. Apabila digunakan di dalam pembina .

    Apabila fungsi digunakan sebagai pembina (iaitu, apabila dipanggil menggunakan kata kunci new 关键字调用时),函数体内的 this), < /p> dalam badan fungsi menghala ke objek baharu yang sedang dibina.

    var myname = "global context";
    function SimpleFun()
    {
        this.myname = "simple function";
    }
    
    var obj1 = new SimpleFun(); //adds myname to obj1
    //1. `new` causes `this` inside the SimpleFun() to point to the
    //   object being constructed thus adding any member
    //   created inside SimipleFun() using this.membername to the
    //   object being constructed
    //2. And by default `new` makes function to return newly 
    //   constructed object if no explicit return value is specified
    
    document.write(obj1.myname); //simple function
    <强>5. Apabila digunakan di dalam fungsi yang ditakrifkan pada rantai prototaip

    🎜

    Jika kaedah berada pada rantai prototaip objek, maka this dalam kaedah merujuk kepada objek yang kaedah dipanggil, seolah-olah kaedah itu ditakrifkan pada objek itu.

    var ProtoObj = {
        fun: function () {
            return this.a;
        }
    };
    //Object.create() creates object with ProtoObj as its
    //prototype and assigns it to obj3, thus making fun() 
    //to be the method on its prototype chain
    
    var obj3 = Object.create(ProtoObj);
    obj3.a = 999;
    document.write(obj3.fun()); //999
    
    //Notice that fun() is defined on obj3's prototype but 
    //`this.a` inside fun() retrieves obj3.a

    <强>6. Fungsi panggilan dalaman(), apply() dan bind()

    • Semua kaedah ini ditakrifkan pada Function.prototype.
    • Kaedah ini membenarkan menulis fungsi sekali dan memanggilnya dalam konteks yang berbeza. Dalam erti kata lain, mereka membenarkan menentukan nilai this yang akan digunakan semasa melaksanakan fungsi. Mereka juga boleh menghantar sebarang hujah kepada fungsi asal apabila ia dipanggil.
    • fun.apply(obj1 [, argsArray])obj1 设置为 this 内的值code>fun() 并调用 fun(),传递 argsArrayfun.apply(obj1 [, argsArray])
    • Tetapkan
    • obj1 kepada nilai dalam code>fun() dan panggil fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - 设置 obj1 作为 fun()this 的值,并调用 fun()fun() , menghantar elemen argsArray sebagai hujahnya. < /code>
    • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - 返回对函数的引用fun,其中 fun 内的 this 绑定到 obj1,并且 fun 的参数绑定到指定的参数 arg1、arg2, arg3,... - Tetapkan obj1 sebagai
    • fun() di dalam
    • nilai, dan memanggil applycallbind 之间的区别一定已经很明显了。 apply 允许将参数指定为类似数组的对象,即具有数字 length 属性和相应的非负整数属性的对象。而 call 允许直接指定函数的参数。 applycallfun() menghantar
    • arg1, arg2, arg3, ...
    sebagai hujahnya.

    thisfun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])

    - Mengembalikan rujukan kepada fungsi fun, di mana menyeronokkan ialah 🎜 terikat kepada 🎜obj1 dan hujah 🎜fun terikat kepada hujah yang ditentukan 🎜arg1, arg2, arg3,.... 🎜 🎜Kini, perbezaan antara 🎜apply, 🎜call dan 🎜bind mestilah jelas. 🎜apply membenarkan hujah ditentukan sebagai objek seperti tatasusunan, iaitu objek dengan sifat 🎜length angka dan sifat integer bukan negatif yang sepadan. Dan 🎜panggilan membolehkan parameter fungsi ditentukan secara langsung. Kedua-dua 🎜apply dan 🎜call segera panggil fungsi dalam konteks yang ditentukan dan dengan parameter yang ditentukan. bind, sebaliknya, hanya mengembalikan fungsi terikat kepada nilai dan argumen ini yang ditentukan. Kita boleh menangkap rujukan kepada fungsi yang dikembalikan ini dengan memberikannya kepada pembolehubah, yang kemudiannya boleh kita panggil pada bila-bila masa. 🎜 🎜
    function add(inc1, inc2)
    {
        return this.a + inc1 + inc2;
    }
    
    var o = { a : 4 };
    document.write(add.call(o, 5, 6)+"
    "); //15 //above add.call(o,5,6) sets `this` inside //add() to `o` and calls add() resulting: // this.a + inc1 + inc2 = // `o.a` i.e. 4 + 5 + 6 = 15 document.write(add.apply(o, [5, 6]) + "
    "); //15 // `o.a` i.e. 4 + 5 + 6 = 15 var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6 document.write(g()+"
    "); //15 var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ? document.write(h(6) + "
    "); //15 // 4 + 5 + 6 = 15 document.write(h() + "
    "); //NaN //no parameter is passed to h() //thus inc2 inside add() is `undefined` //4 + 5 + undefined = NaN
    🎜🎜7. 🎜🎜🎜 di dalam pengendali acara
    • Apabila anda menetapkan fungsi terus kepada pengendali acara elemen, ini dilakukan menggunakan kaedah pendaftaran acara tradisional seperti this 来引用相应的元素。这种直接的函数分配可以使用 addeventListener 方法或通过 onclick terus dalam fungsi pengendali acara.
    • Begitu juga, apabila anda memanggil atribut acara elemen seperti
    • Walau bagaimanapun, this 会解析为全局对象 window digunakan secara tidak langsung melalui fungsi lain yang dipanggil dalam pengendali acara atau sifat acara.
    • Tingkah laku yang sama seperti di atas boleh dicapai apabila kami menggunakan pendekatan model pendaftaran acara Microsoft attachEvent untuk melampirkan fungsi pada pengendali acara. Daripada memberikan fungsi kepada pengendali acara (dengan itu mencipta kaedah fungsi elemen), ia memanggil fungsi pada acara (dengan berkesan memanggilnya dalam konteks global).

    Saya syorkan JSFiddle.

    sssccc
    
    

    Using `this` "directly" inside event handler or event property



    Using `this` "indirectly" inside event handler or event property



    IE only:

    <强>8. this

    dalam fungsi anak panah ES6

    Dalam fungsi anak panah, this 的行为类似于公共变量:它将从其词法范围继承。定义箭头函数的函数的 this 将是箭头函数的 this berkelakuan seperti pembolehubah awam: ia akan diwarisi daripada skop leksikalnya.

    fungsi yang mentakrifkan fungsi anak panah akan menjadi

    fungsi anak panah.

    Jadi, ini adalah kelakuan yang sama seperti:

    (function(){}).bind(this)
    🎜Lihat kod di bawah: 🎜
    const globalArrowFunction = () => {
      return this;
    };
    
    console.log(globalArrowFunction()); //window
    
    const contextObject = {
      method1: () => {return this},
      method2: function(){
        return () => {return this};
      }
    };
    
    console.log(contextObject.method1()); //window
    
    const contextLessFunction = contextObject.method1;
    
    console.log(contextLessFunction()); //window
    
    console.log(contextObject.method2()()) //contextObject
    
    const innerArrowFunction = contextObject.method2();
    
    console.log(innerArrowFunction()); //contextObject 
    

    balas
    0
  • P粉156532706

    P粉1565327062023-10-13 11:53:32

    ialah kata kunci dalam JavaScript yang merupakan atribut konteks pelaksanaan. Penggunaan utamanya adalah dalam fungsi dan pembina. this Peraturannya agak mudah (jika anda berpegang kepada amalan terbaik).

    Penerangan teknikalthis dalam spesifikasi

    ECMAScript standarddefinisithis melalui operasi abstrak (disingkatkan sebagai AO) ResolveThisBinding:

    Rekod persekitaran global, Rekod persekitaran modul, dan Rekod persekitaran fungsi masing-masing mempunyai kaedah GetThisBinding mereka sendiri.

    GetThisEnvironment AO mencari LexicalEnvironment bagi konteks pelaksanaan menjalankan semasa dan mencari rekod persekitaran menaik yang paling hampir (dengan mengulangi sifat [[OuterEnv]]nya) yang mempunyai ini< /em> mengikat ini mengikat

    ini

    . . Proses ini berakhir dengan satu daripada tiga jenis rekod persekitaran. this Nilai biasanya bergantung pada sama ada kod berada dalam

    mod ketat

    . this 值,因此每当建立新的执行上下文时,this Nilai pulangan

    GetThisBinding mencerminkan nilai

    konteks pelaksanaan semasa, jadi setiap kali konteks pelaksanaan baharu diwujudkan, akan menyelesaikan kepada nilai yang berbeza. Ini juga boleh berlaku apabila konteks pelaksanaan semasa diubah suai. Subseksyen berikut menyenaraikan lima senario di mana ini mungkin berlaku.

    Anda boleh meletakkan sampel kod ke dalam

    AST Explorer

    untuk mengikuti butiran spesifikasi.

    1. Konteks pelaksanaan global dalam skrip

    Ini ialah kod skrip yang dinilai di peringkat teratas, mis this Apabila dalam konteks pelaksanaan global awal skrip, menilai menyebabkan

    GetThisBinding🎜 mengambil langkah berikut: 🎜

    Harta [[GlobalThisValue]] rekod persekitaran global sentiasa ditetapkan kepada objek global yang ditentukan hos, boleh diakses melalui globalThisglobalThis ( Web 上的 window,Node.js 上的 global (tetingkap di web , Node.js global Dokumentasi di MDN). Ikuti langkah InitializeHostDefinedRealm untuk mengetahui cara sifat [[GlobalThisValue]] dijana.

    2. Konteks pelaksanaan global dalam modul

    Modul telah diperkenalkan dalam ECMAScript 2015.

    Ini berfungsi untuk modul cth.