في الواقع ، هذه قضية كليشيهات. هناك الكثير من المقالات حول هذا الموضوع. في الواقع ، اعتقدت أنني قد اكتشفت ذلك ، لكن بالأمس ، لا يزال لدي القليل من الشك أثناء المشروع. فكرت في مقال مفصل قمت بجمعه وقرأته في JavaScript Weekly (كان هناك رابط لاحقًا ، وتم إرفاق الترجمة الصينية على الأرض النادرة) ومقالًا آخر أوصى به أحد كبار ، لذلك نظرت إليهم وفهم هذا قد تحسن قليلاً.
"هذا" في JavaScript ديناميكي ويتم تحديده عند تشغيل الوظيفة ، وليس عند الإعلان عن الوظيفة. يمكن لجميع الوظائف استدعاء "هذا" ، وهو ما لا يهم إذا كانت الوظيفة تنتمي إلى كائن. فيما يتعلق بهذا ، هناك بشكل أساسي أربع حالات.
1. تسمى الطريقة المستخدمة ككائن
إذا كانت الوظيفة طريقة تعتبر ككائن ، فإن هذه الوظيفة تشير إلى الكائن ؛
var john = {firstName: "John"} funct func () {Alert (this.firstName + ": hi!)} john.sayhi = func john.sayhi ()هناك شيء يستحق الإشارة هنا. عندما يتم إخراج طريقة الكائن وتعيينها إلى متغير ، تصبح الطريقة مشغل دالة ، وهذا يشير إلى النافذة أو UnderFind (الوضع الصارم).
2. اتصل ضمن الوظيفة
عندما تحتوي هذه الوظيفة على هذه ، فهذا يعني في الواقع أنه يطلق عليها كوسيلة. إن الاتصال بين الاثنين يعادل معاملته ككائن نافذة. هذا يشير إلى النافذة. تجدر الإشارة إلى أن ES5 ينص في الواقع على أن هذا = غير محدد ، ولا يزال يتم تنفيذ المتصفحات فقط وفقًا للطريقة القديمة (أختبره في أحدث إصدار من Chrome و Safari و Firefox ، كل نقطة إلى نافذة (201607)) ، واستخدام وضع صارم للإشارة إلى Firefox ؛
func () وظيفة func () {Alert (this) // [woffice window] أو [Object Global] أو نوع ..}لتمرير هذا ، () يجب أن يكون نوعًا مرجعيًا من قبل ، على غرار OBJ.A أو OBJ ['a'] ، ولا يمكن أن يكون أي شيء آخر.
هناك أيضا حفرة صغيرة هنا. عندما تكون هناك وظيفة في طريقة الكائن ، يتم تشغيل الوظيفة فعليًا كوضع وظيفة ، لذلك فإن هذا الافتراضات إلى النافذة (غير محددة في الوضع الصارم). الحل هو ربط هذا بالوظيفة.
var numbers = {numbera: 5 ، numberb: 10 ، sum: function () {console.log (this === number) ؛ // => function true calculate () {// هذا هو نافذة أو غير محددة في console.log الوضع الصارم (هذا === الأرقام) ؛ // => false return this.numbera + this.numberb ؛ } إرجاع حساب () ؛ }} ؛ number.sum () ؛ // => nan أو throws typeerror في وضع var number {numbera: 5 ، numberb: 10 ، sum: function () {console.log (this === number) ؛ // => function true calculate () {console.log (this === number) ؛ // => true return this.numbera + this.numberb ؛ } // استخدام .Call () طريقة لتعديل إرجاع السياق calculate.call (هذا) ؛ }} ؛ number.sum () ؛ // => 153. اتصل في الجديد
المتغير الذي يشير إلى كائن يحفظ بالفعل مرجعًا إلى الكائن ، أي أن المتغير يحفظ بالفعل مؤشرًا إلى البيانات الحقيقية.
عند استخدام الكلمة الرئيسية الجديدة ، يتخذ هذا التغيير في الواقع الخطوات التالية:
إنشاء هذا = {}.
يمكن تغيير هذا أثناء تنفيذ جديد ، ثم تتم إضافة السمات والأساليب ؛
إرجاع هذا تغير.
وظيفة animal (name) {this.name = name this.canwalk = true} var animal = new Animal ("Beastie") ALERT (Animal.Name)تجدر الإشارة إلى أنه إذا قام المُنشئ بإرجاع كائن ، فإن هذا يشير إلى الكائن الذي تم إرجاعه ؛
وظيفة animal () {this.name = 'mousie' ؛ this.age = '18' ؛ إرجاع {name: 'Godzilla'} // <- سيتم إرجاع} var animal = new Animal () console.log (Animal.name)من المهم أن نلاحظ هنا أنه لا تنس استخدام جديد ، وإلا فلن يتم إنشاء وظيفة جديدة. بدلاً من ذلك ، فإنه ينفذ الوظيفة ، وهو ما يعادل مكالمة الوظائف ، وهذا يشير فعليًا إلى النافذة
وظيفة مركبة (type ، wheelscount) {this.type = type ؛ this.wheelscount = wheelscount ؛ إرجاع هذا ؛} // وظيفة invocationVar Car = مركبة ('Car' ، 4) ؛ car.type ؛ // => 'car' car.wheelscount // => 4 car === window // => true4. استدعاء هذا بوضوح ، استخدم المكالمة والتطبيق
هذا هو المكان الأكثر إلهاما جافا سكريبت.
الرمز التالي:
func.call(obj, arg1, arg2,...)
سيتم استخدام المعلمة الأولى ككائن مرجعي لهذا ، وسيتم استخدام المعلمة اللاحقة كمعلمة للدالة. الحل هو استخدام الربط.
وظيفة animal (النوع ، الساقين) {this.type = type ؛ this.legs = الساقين ؛ this.loginfo = function () {console.log (this === mycat) ؛ // => true console.log ('' + this.type + 'has' + this.legs + 'legs') ؛ } ؛} var mycat = new Animal ('cat' ، 4) ؛ // logs "The Cat has 4 legs" setTimeout (mycat.loginfo.bind (mycat) ، 1000) ؛ // settimeout ؟؟ var john = {firstName: "John" ، الحادث: "Smith"} Function func (a ، b) {Alert (this [a] + '' + this [b])} func.call (John ، 'FirstName' ، 'surname') // "John Smith"بالنسبة للتطبيق ، فإنه يمر فقط في المعلمات في مربع الصفيف ، والأجزاء الأخرى هي نفسها ، كما يلي:
func.call (John ، 'FirstName' ، 'surnme') func.apply (John ، ['FirstName' ، 'surname'])
يمكن استخدامها أيضًا في ميراث الفصل في ES5 لاستدعاء مُنشئ الأصل.
وظيفة Runner (name) {console.log (هذا مثيل الأرنب) ؛ // => true this.name = name ؛ } وظيفة الأرنب (الاسم ، countlegs) {console.log (هذا مثيل الأرنب) ؛ // => true // يسمى بشكل غير مباشر ، The Parent Constructor Runner.Call (هذا ، الاسم) ؛ this.countlegs = countlegs ؛ } var myRabbit = New Rabbit ('White Rabbit' ، 4) ؛ myrabbit // {name: 'White Rabbit' ، Countlegs: 4}5..bind ()
قارن بين الطرق .apply () و .call () ، وكلاهما ينفذ الوظيفة على الفور ، بينما تقوم دالة .bind () بإرجاع طريقة جديدة تربط هذه المحددة مسبقًا ويمكنها تأخير المكالمة.
وظيفة طريقة .bind () هي إنشاء وظيفة جديدة. السياق أثناء التنفيذ هو المعلمة الأولى التي تم تمريرها بواسطة .bind () ، والتي تسمح بإنشاء وظيفة لها هذه الإعدادات المسبقة.
var numbers = {array: [3 ، 5 ، 10] ، getNumbers: function () {return this.array ؛ }} ؛ // إنشاء وظيفة ملزمة boundgetNumbers = number.getNumbers.bind (الأرقام) ؛ boundgetnumbers () ؛ // => [3 ، 5 ، 10]. SimpleGetNumbers () ؛ // => غير محدد أو يرمي خطأ في الوضع الصارمعند استخدام .bind () ، يجب أن تلاحظ أن .bind () ينشئ سلسلة سياق أبدية ولا يمكن تعديلها. حتى إذا كانت وظيفة الربط تستخدم .Call () أو .apply () للانتقال إلى سياقات أخرى مختلفة ، فلن تغير سياق اتصالها السابق ، ولن يلعب إعادة التوليد أي دور.
فقط عندما يتم استدعاء المنشئ ، يمكن أن تغير وظيفة الربط السياق ، ولكن هذا ليس نهجًا موصى به بشكل خاص.
6. وظيفة السهم
لا تنشئ وظيفة السهم سياق تنفيذها ، بحيث يعتمد هذا على الوظيفة الخارجية التي يتم تعريفها في وقت التعريف.
لا يمكن تغيير وظائف السهم بعد ربط السياق مرة واحدة ، حتى لو تم استخدام طريقة تغيير السياق:
VAR NUMBERS = [1 ، 2] ؛ (function () {var get = () => {console.log (this === number) ؛ // => return this ؛} ؛ console.log (this === number) ؛ // => true get () ؛ // => [1 ، 2] // => [1 ، 2] // BIND GET.Bind ([0]) () ؛وذلك لأن وظيفة السهم لها سياق ثابت ولن يتغير بسبب مكالمات مختلفة. لذلك ، لا تستخدم وظائف السهم لتحديد الطرق
فترة الوظيفة (ساعات ، دقائق) {this.hours = ساعات ؛ this.minutes = دقائق ؛ } pare.prototype.format = () => {console.log (this === window) ؛ // => true return this.hours + 'Hours و' + this.minutes + 'Minots' ؛ } ؛ var walkperiod = فترة جديدة (2 ، 30) ؛ walkperiod.format () ؛ // => "ساعات غير محددة ودقائق غير محددة"الرجوع إلى
أربع روائح "هذا"
شرح لطيف للكلمة "هذه" في جافا سكريبت
JavaScript هذا اللغز (الترجمة)
يوصى بشدة أن يقوم الطلاب الذين لا يفهمون ذلك. تحقق من المقالات الثلاثة المذكورة أعلاه ، والمقالات الثالثة هي ترجمة المقالات الثانية. إذا كان لديك أي أسئلة حول هذا ، فأنت مرحب بك للمناقشة معًا والتواصل وتعزيز التفكير وتحقيق التقدم معًا.