نظرة عامة مفاهيمية هذا
عند إنشاء وظيفة ، يتم إنشاء كلمة رئيسية (في الخلفية) ، والتي ترتبط بكائن ، وتعمل الوظيفة في هذا الكائن. بمعنى آخر ، يمكن استخدام الكلمة الرئيسية التي يمكن استخدامها في دالة ، مرجع إلى كائن ، والوظيفة هي الخاصية أو طريقة هذا الكائن.
دعونا نلقي نظرة على هذا الكائن:
<! doctype html> <html lang = "en"> <body> <script> var code = {Living: True ، العمر: 23 ، الجنس: 'ذكر' ، getGender: function () {return cody.gender ؛}} ؛ console.log (cody.getgender ()) ؛ // سجلات 'ذكر' </script> </body> </html>لاحظ أنه في وظيفة getGender ، نظرًا لأن داخل كائن Cody ، يمكننا الحصول على سمة الجنس (أي ، cody.gender) من خلال. يمكنك أيضًا استخدام هذا للحصول على كائن Cody ، لأن هذا يشير إلى كائن Cody.
<! doctype html> <html lang = "en"> <body> <script> var code = {Living: True ، العمر: 23 ، الجنس: 'ذكر' ، getGender: function () {return this.gender ؛}} ؛ console.log (cody.getgender ()) ؛ // سجلات 'ذكر' </script> </body> </html>في this.gender ، يشير هذا إلى كائن Cody ، ويمكن أن تعمل وظيفة getGender على كائن Cody.
قد يكون الموضوع حول هذا الأمر مربكًا بعض الشيء ، لكن لا يجب أن يكون كذلك. فقط تذكر أنه عادة ما يشير هذا الكائن إلى الكائن الذي يحتوي على الوظيفة ، وليس الوظيفة نفسها (بالطبع هناك استثناءات ، مثل استخدام الكلمات الرئيسية الجديدة أو الاتصال () وتطبيق ()).
نصائح مهمة
- الكلمة الرئيسية التي تشبه المتغيرات الأخرى ، والفرق الوحيد هو أنه لا يمكنك تغييرها.
- على عكس المعلمات والمتغيرات الأخرى التي تم تمريرها إلى وظيفة ، فهذه كلمة رئيسية (وليس خاصية) في الكائن الذي يدعو الوظيفة.
كيف تحدد قيمة هذا؟
يتم تمرير هذا إلى جميع الوظائف ، وتعتمد قيمتها على متى يتم استدعاء الوظيفة عند تشغيلها. يرجى ملاحظة هنا ، لأن هذا مكان خاص للغاية تحتاج إلى تذكره.
في الكود التالي ، يحتوي كائن MyObject على خاصية Sealfo ، والتي تشير إلى الوظيفة Sealfoo. عندما يتم استدعاء وظيفة Sayfoo في المجال العالمي ، يشير هذا إلى كائن النافذة. عندما يستدعي MyObject وظيفة ، يشير هذا إلى MyObject.
لأن MyObject لديها خاصية تسمى Foo ، يتم استخدامها هنا.
<! doctype html> <html lang = "en"> <body> <script> var foo = 'foo' ؛ var myobject = {foo: 'أنا myobject.foo'} ؛ var sayfoo = function () {console.log (this ['foo']) ؛ } ؛ // أعط myobject خاصية sayfoo واطلب من وظيفة sayfoo myobject.sayfoo = sayfoo ؛ myobject.sayfoo () ؛ // logs 'أنا myobject.foo' 12 sayfoo () ؛ // سجلات 'foo' </script> </body> </html>من الواضح أن قيمة هذا تعتمد على متى يتم استدعاء الوظيفة. يشير MyObject.Sayfoo و Sayfoo إلى نفس الوظيفة ، لكن سياق استدعاء Sayfoo () مختلف ، وبالتالي فإن قيمة هذا مختلفة. فيما يلي رمز مماثل ، يتم استخدام كائن الرأس (النافذة) بشكل صريح ، على أمل أن يكون مفيدًا لك.
<! doctype html> <html lang = "en"> <body> <script> window.foo = 'foo' ؛ window.myobject = {foo: 'أنا myobject.foo'} ؛ window.sayfoo = function () {! console.log (this.foo) ؛ } ؛ window.myobject.sayfoo = window.sayfoo ؛ window.myobject.sayfoo () ؛ window.sayfoo () ؛ </script> </body> </html>تأكد من أنه عندما يكون لديك مراجع متعددة تشير إلى نفس الوظيفة ، فأنت تعلم بوضوح أن قيمة هذا يتغير اعتمادًا على سياق وظيفة الاتصال.
نصائح مهمة
- جميع المتغيرات والمعلمات باستثناء هذا ينتمي إلى النطاق المتغير الثابت.
هذا يشير إلى كائن الرأس داخل الوظيفة المدمجة
قد تتساءل عما يحدث عند استخدام هذا في وظيفة مضمنة في وظيفة أخرى. لسوء الحظ في ECMA 3 ، لا يتبع هذا القواعد ، فهو لا يشير إلى الكائن الذي تنتمي إليه الوظيفة ، ولكن إلى كائن الرأس (كائن نافذة المتصفح).
في الكود التالي ، لم يعد هذا في FUNC2 و FUNC3 يشير إلى MyObject ، بل هو كائن الرأس.
<! doctype html> <html lang = "en"> <body> <script> var myobject = {func1: function () {console.log (this) ؛ // سجلات myObject varfunc2 = function () {console.log (this) ؛ // WORDS WINDOW ، وسوف تفعل ذلك من هذه النقطة على varfunc3 = function () {console.log (this) ؛ // نافذة سجلات ، كما هو كائن الرأس} () ؛ } () ؛ }} ؛ myobject.func1 () ؛ </script> </body> </html>ومع ذلك ، في ECMASCRIPT 5 ، سيتم تصحيح هذه المشكلة. الآن يجب أن تكون على دراية بهذه المشكلة ، خاصة عندما تنقل قيمة وظيفة إلى أخرى.
انظر إلى الكود أدناه ، مرر دالة مجهولة إلى foo.func1. عندما يتم استدعاء دالة مجهولة في foo.func1 (يتم تداخل الوظيفة في وظيفة أخرى) ، سيشير هذا إلى كائن الرأس في الدالة المجهولة.
<! doctype html> <html lang = "en"> <body> <script> var foo = {func1: function (bar) {bar () ؛ // window window ، وليس foo console.log (this) ؛ // ستكون هذه الكلمة الرئيسية هنا مرجعًا إلى Foo Object}} ؛ foo.func1 (function () {console.log (this)}) ؛ </script> </body> </html>الآن لن تنسى أنه إذا كانت الوظيفة التي تحتوي على هذه في وظيفة أخرى ، أو تسمى وظيفة أخرى ، فإن قيمة ذلك ستشير إلى كائن الرأس (مرة أخرى ، سيتم تصحيح ذلك في ECMASCRIPT 5.)
حل مشكلة الوظائف المتداخلة
من أجل منع ذلك ، يمكنك استخدام سلسلة نطاق في وظيفة الأصل لحفظ المراجع إلى هذا. في الكود التالي ، باستخدام متغير يسمى ذلك ، باستخدام نطاقه ، يمكننا حفظ سياق الوظيفة بشكل أفضل.
<! doctype html> <html lang = "en"> <body> <script> var myObject = {myProperty: 'icanseeHelight' ، mymethod: function () {var that = this ؛ // قم بتخزين إشارة إلى هذا (iEmyObject) في وظيفة mymethod scope varhelperfunction () {// childfunction var helperfunction function () {// childfunction // logs 'يمكنني رؤية الضوء عبر سلسلة النطاق لأن هذا = console.log (that.myproperty) ؛ // سجلات "يمكنني رؤية Console.log (هذا) ؛ // logs window object ، إذا لم نستخدم "ذلك"} () ؛ }} myobject.mymethod () ؛ // استدعاء mymethod </script> </body> </html>تحكم في قيمة هذا
تعتمد قيمة هذا عادةً على السياق الذي تسمى الوظيفة (ما لم يتم استخدام الكلمة الرئيسية الجديدة ، والتي سيتم تقديمها لاحقًا) ، ولكن يمكنك استخدام تطبيق () أو الاتصال () لتحديد الكائن الذي يشير إلى ذلك عندما يتم تشغيل وظيفة لتغيير/التحكم في قيمة هذا. إن استخدام هاتين الطريقتين يشبه القول مرة أخرى: "مهلا ، اتصل بوظيفة X ، ولكن دع كائن Z يجعل هذه القيمة." القيام بذلك ، سيتم تغيير القيمة الافتراضية لهذا JavaScript.
أدناه ، نقوم بإنشاء كائن ودالة ، ثم نؤدي إلى تشغيل الوظيفة من خلال Call () ، لذلك هذا في الوظيفة يشير إلى myojbect. يعمل هذا في وظيفة MyFunction على myobject بدلاً من كائن الرأس ، لذلك نقوم بتغيير الكائن الذي أشار إليه هذا في MyFunction.
<! doctype html> <html lang = "en"> <body> <script> var myobject = {} ؛ var myfunction = function (param1 ، param2) {// setViacall () 'this''spoints إلى كائني عندما يتم استدعاء الدالة this.foo = param1 ؛ this.bar = param2 ؛ console.log (هذا) ؛ // logs object {foo = 'foo' ، bar = 'bar'}} ؛ myfunction.call (myobject ، 'foo' ، 'bar') ؛ // invoke function ، اضبط هذه القيمة على myobject console.log (myobject) // سجلات الكائن {foo = 'foo' ، bar = 'bar'} </script> </body> </html>في المثال أعلاه ، استخدمنا Call () ، يمكن أيضًا تطبيق تطبيق () على نفس الاستخدام. الفرق بين الاثنين هو كيفية نقل المعلمات إلى الوظيفة. استخدم Call () ، يتم فصل المعلمات عن طريق الفواصل ، وتطبيق () ، ويتم تمرير المعلمات في صفيف. فيما يلي نفس الرمز ، ولكن استخدم تطبيق ().
<! doctype html> <html lang = "en"> <body> <script> var myobject = {} ؛ var myfunction = function (param1 ، param2) {// set عبر تطبيق () ، هذا يشير إلى كائني عندما يتم استدعاء الدالة this.foo = param1 ؛ this.bar = param2 ؛ console.log (هذا) ؛ // logs object {foo = 'foo' ، bar = 'bar'}} ؛ myfunction.apply (myobject ، ['foo' ، 'bar']) ؛ // invoke function ، قم بتعيين قيمة console.log (myobject) ؛ // سجلات كائن {foo = 'foo' ، bar = 'bar'} </script> </body> </html>استخدم هذا في مُنشئ مخصص
عندما يتم تشغيل الوظيفة مع الكلمة الرئيسية الجديدة ، يتم الإعلان عن قيمة ذلك في المنشئ للإشارة إلى المثيل نفسه. بمعنى آخر: في المُنشئ ، يمكننا استخدام هذا لتحديد الكائن قبل إنشاءه بالفعل. يبدو أن هذا يغير هذه القيمة للاتصال () أو تطبيق ().
أدناه ، نقوم ببناء شخص مُنشئ ، والذي يشير إلى الكائن الذي تم إنشاؤه. عند إنشاء كائن الشخص ، يشير هذا إلى هذا الكائن ويضع اسم الخاصية في الكائن ، والقيمة هي قيمة المعلمة (الاسم) التي تم تمريرها إلى هذا المُنشئ.
<! doctype html> <html lang = "en"> <body> <script> var person = function (name) {this.name = name || 'Johndoe' ؛ // سيشير هذا إلى الفوري الذي تم إنشاؤه} var code = شخص جديد ('Cody Lindley') ؛ // إنشاء مثيل ، استنادًا إلى console.log console.log (cody.name) ؛ // سجلات 'Cody Lindley' </script> </body> </html>وبهذه الطريقة ، عندما يتم تشغيل المنشئ مع الكلمة الرئيسية الجديدة ، فإن هذا يشير إلى "كائن ليتم إنشاؤه". ثم إذا لم نستخدم الكلمة الرئيسية الجديدة ، فستشير قيمة هذا إلى السياق الذي يثير الشخص - هذا هو كائن الرأس. لنلقي نظرة على الكود أدناه.
<! doctype html> <html lang = "en"> <body> <script> var person = function (name) {this.name = name || 'Johndoe' ؛ } var code = person ('Cody Lindley') ؛ // لاحظ أننا لم نستخدم "console.log" "cody.name)" cody.name) ؛ // غير محدد ، يتم تعيين القيمة فعليًا على window.name console.log (window.name) ؛ // سجلات 'Cody Lindley' </script> </body> </html>هذا يشير إلى مثيل المنشئ داخل طريقة النموذج الأولي
عند استخدام طريقة ما كخاصية النموذج الأولي لمؤسس ، يشير هذا في هذه الطريقة إلى مثيل لطريقة الزناد. هنا ، لدينا شخص () مُنشئ ، والذي يتطلب الاسم الكامل للشخص. من أجل الحصول على الاسم الكامل ، نضيف طريقة وماذا عن شخص إلى الشخص. هذا في هذه الطريقة يشير إلى المثيل (وخصائصه) التي أثارت هذه الطريقة.
أدناه قمت بإنشاء كائنين من شخصين (Cody و LISA) ، وتتضمن طريقة WhatismyfullName الموروثة هذه النقطة إلى هذه الحالة.
<! doctype html> <html lang = "en"> <body> <script> var person = function (x) {if (x) {this.fullName = x} ؛ } ؛ person.prototype.whatismyfullName = function () {return this.fullName ؛ // "هذا" يشير إلى المثيل الذي تم إنشاؤه من person ()} var code = شخص جديد ('cody lindley') ؛ var lisa = شخص جديد ('Lisa Lindley') ؛ // استدعاء طريقة WhatismyfullName الموروثة ، والتي تستخدم هذا للإشارة إلى Console.log مثيل (cody.whatismyfullname () ، lisa.whatismyfullname ()) ؛ /* لا تزال سلسلة النموذج الأولي ساري المفعول ، لذلك إذا لم يكن للمثال خاصية اسم FullName ، فستبحث عنها في سلسلة النموذج الأولي. أدناه ، نضيف خاصية fullname إلى كل من النموذج الأولي للنموذج والنموذج الأولي للكائن. انظر الملاحظات. */object.prototype.fullName = 'John doe' ؛ var John = شخص جديد () ؛ // لا يتم تمرير أي حجة حتى لا يتم إضافة اسم Fullname إلى console.log (john.hatismyfullname ()) ؛ // سجلات 'John doe' </script> </body> </html>استخدم هذا في الطريقة داخل كائن النموذج الأولي ، وهذا يشير إلى المثيل. إذا لم يحتوي المثيل على سمات ، يبدأ البحث النموذج الأولي.
تَلمِيح
- إذا كان الكائن الذي يشير إلى هذا لا يحتوي على السمات التي تريد العثور عليها ، فإن القانون الذي ينطبق على أي سمات ينطبق أيضًا هنا ، أي أن السمات سيتم "تفتيشها" على طول سلسلة النموذج الأولي. لذلك في مثالنا ، إذا لم يكن المثيل يحتوي على خاصية FullName ، فسيبحث الاسم الكامل عن profote.prototype.fullname ، ثم object.prototype.fullname.
لعرض المزيد من بناء جملة JavaScript ، يمكنك متابعة: "دليل JavaScript Reference Tutorial" و "JavaScript Code Style". آمل أيضًا أن يدعم الجميع wulin.com أكثر.