لماذا يتم تضمين فئة JavaScript في استدعاء دالة مجهولة ()؟

StackOverflow https://stackoverflow.com//questions/12692250

  •  12-12-2019
  •  | 
  •  

سؤال

كنت أقرأ عن لغة جديدة تشبه JavaScript من Microsoft تسمى تايب سكريبت.في ال ملعب (القسم سبيل المثال), ، هناك فئة بسيطة في بناء جملة TypeScript تم تحويلها إلى كود JavaScript.نظرًا لخبرتي في برمجة Java، كان من المثير للاهتمام بالنسبة لي أن أتعلم كيفية عمل OOP في JavaScript كما تم تجميعه من TypeScript.

كود تايب سكريبت:

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}   

var greeter = new Greeter("world");

var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
    alert(greeter.greet())
}

document.body.appendChild(button)

وكود جافا سكريبت المكافئ:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

جزء Typescript مشابه جدًا لـ Java لذا أفهم ذلك.الآن سؤالي هو لماذا في جافا سكريبت نص Greeter تم تضمين الطبقة في مجهول function() يتصل؟

لماذا لا تكتبها هكذا؟

function Greeter(message) {
    this.greeting = message;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

ما هي ميزة/عيب كل طريقة؟

هل كانت مفيدة؟

المحلول

ما يلي يسمى تم استدعاء تعبير الوظيفة على الفور:

(function(){ ... })();

يتم استخدامه للحفاظ على النطاق العالمي نظيفًا.على الرغم من ذلك، في هذه الحالة ليس من الضروري حيث يتم تعيين قيمة الإرجاع لمتغير Greeter.المرة الوحيدة التي يكون فيها هذا النمط مفيدًا هي عندما تريد "خاصًا" ثابتة أعضاء.

على سبيل المثال:

var Greeter = (function () {
    var foo = 'foo', bar = 'bar'; /* only accessible from function's defined
                                     in the local scope ... */

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

نصائح أخرى

هذا للسماح للأعضاء الخاصين.في هذا المثال، جميع الأعضاء عامون، لذا فإن البناءين الخاصين بك متساويان.ومع ذلك، إذا كنت تريد توفير أعضاء خاصين، فأنت بحاجة إلى إخفائهم من نطاق الاتصال عبر الإغلاق.وبالتالي إذا كان لديك عضو خاص مثل ذلك:

class Greeter {
    private greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
} 

ربما ستحصل على شيء مثل هذا:

var Greeter = (function () {
    var greeting="";
    function Greeter(message) {
        greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + greeting;
    };
    return Greeter;
})();

سيكون متغير الترحيب متاحًا لأي وظيفة محددة داخل الوظيفة المجهولة، ولكنه غير مرئي في أي مكان آخر.

إلى جانب المنطق الواضح للنطاق/الإغلاق.يؤدي استخدام وظيفة مجهولة تستدعي نفسها على الفور إلى تحميل (تفسير) تعريف الفئة مسبقًا.يسمح هذا بتحميل أي تحسينات JIT في المقدمة أثناء التنفيذ.باختصار، بالنسبة للتطبيقات الأكبر حجمًا والأكثر تعقيدًا، سيؤدي ذلك إلى تحسين الأداء.

عادةً ما يتم استخدام الوظيفة المجهولة / الإغلاق ذاتي التنفيذ لتغليف النطاق بحيث لا يمكن الوصول إلا إلى القيمة التي تم إرجاعها خارج النطاق.(أو أي شيء تعلقه بأشياء أخرى، مثل النافذة)

من المحتمل أن تكون الوظيفة المجهولة موجودة لمنع تضارب الأسماء مع أجزاء أخرى من الكود.فكر في الأمر بهذه الطريقة، داخل وظيفتك المجهولة، يمكنك حتى إعلان متغير يسمى "$" ليكون ما تريد، وفي الوقت نفسه، يمكنك استخدام jQuery في أجزاء أخرى من التعليمات البرمجية الخاصة بك دون تعارض.

الإغلاق هو الوسيلة الوحيدة لاستدعاء المُنشئين باستخدام المعلمات:

var w = new Greeter("hello")

هناك طرق أخرى ولكنها كلها معقدة ولها قيود وعيوب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top