سؤال

قصة قصيرة طويلة: أنا في موقف، حيث أود الحصول على طراز PHP، ولكن في جافا سكريبت.

بلدي JavaScript يعمل في Firefox فقط، لذلك Mozilla محددة JS هو موافق بي.

الطريقة الوحيدة التي يمكنني العثور عليها لجعل JS Getter يتطلب تحديد اسمها، لكنني أرغب في تحديد Getter for الكل الأسماء الممكنة. لست متأكدا مما إذا كان ذلك ممكنا، لكنني أود أن أعرف ذلك كثيرا.

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

المحلول

Proxy تستطيع ان تفعل ذلك! أنا سعيد للغاية هذا موجود !! يتم إعطاء إجابة هنا: هل هناك ما يعادل جافا سكريبت من طريقة Python's __getattr__؟ وبعد لإعادة صياغة كلماتي الخاصة:

var x = new Proxy({},{get(target,name) {
  return "Its hilarious you think I have "+name
}})

console.log(x.hair) // logs: "Its hilarious you think I have hair"

وكيل للفوز! تحقق من مستندات MDN: https:/developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/proxy.

يعمل في Chrome و Firefox و Node.js.js. Downsides: لا يعمل في IE - Freakin IE. هكذا.

نصائح أخرى

الأقرب الذي يمكنك العثور عليه هو __nosuchmethod__, ، وهو ما يعادل JavaScript الخاص ب PHP's __call ().

لسوء الحظ، ليس هناك ما يعادل __et / __ مجموعة، وهو عار، لأنه معهم قد نفذينا __nosuchmethod__، لكنني لا أرى بعد طريقة لتنفيذ الخصائص (كما في C #) باستخدام __nosuchmethod__.

var foo = {
    __noSuchMethod__ : function(id, args) {
        alert(id);
        alert(args);
    }
};

foo.bar(1, 2);

إذا كنت ترميز في ES6، يمكنك الجمع بين الوكيل والطبق للحصول على لطيفة النظر رمز مثل php:

class Magic {
    constructor () {
        return new Proxy(this, this);
    }
    get (target, prop) {
        return this[prop] || 'MAGIC';
    }
}

هذا يرتبط بالمعالج، حتى تتمكن من استخدام هذا بدلا من الهدف.

ملاحظة: على عكس php، يعالج الوكيل جميع طلب الخاصية.

let magic = new Magic();
magic.foo = 'NOT MAGIC';
console.log(magic.foo); // NOT MAGIC
console.log(magic.bar); // MAGIC

يمكنك التحقق من المتصفحات التي تدعم الوكيل http://caniuse.com/#Feat=Proxy. والطبقة http://caniuse.com/#Feat=es6-Class.. وبعد عقدة 8 دعم كليهما.

جافا سكريبت 1.5. لديه getter / studter. التجميل اللغوى. وبعد وأوضح جيدا من قبل جون ريسج هنا

إنه ليس عاما بما فيه الكفاية لاستخدام الويب، ولكن بالتأكيد فايرفوكس لديه (وحيد القرن أيضا، إذا كنت ترغب في استخدامه على جانب الخادم).

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

var foo = {
    args: {},

    __noSuchMethod__ : function(id, args) {
        if(args === undefined) {
            return this.args[id] === undefined ? this[id] : this.args[id]
        }

        if(this[id] === undefined) {
            this.args[id] = args;
        } else {
            this[id] = args;
        }
    }
};

إذا كنت تبحث عن شيء مثل PHP __get() وظيفة، لا أعتقد أن JavaScript توفر أي بناء من هذا القبيل.

أفضل ما يمكنني التفكير فيه هو حلقات من خلال أعضاء الكائن غير الوظيفة ثم إنشاء وظيفة "GetXyz ()" المقابلة لكل منها.

في DODGY PSEDO-ISH رمز:

for (o in this) {
    if (this.hasOwnProperty(o)) {
        this['get_' + o] = function() {
            // return this.o -- but you'll need to create a closure to
            // keep the correct reference to "o"
        };
    }
}

انتهى بي الأمر باستخدام إجابة Nickfs لإنشاء حل الخاص بي. سيؤدي حلاي تلقائيا إلى إنشاء get_ {propame} و set_ {propame} الوظائف لجميع الخصائص. إنه يتحقق مما إذا كانت الوظيفة موجودة بالفعل قبل إضافةها. يتيح لك ذلك تجاوز طريقة التعيين أو تعيينها الافتراضية مع تطبيقنا الخاص دون خطر الكتابة فوقها.

for (o in this) {
        if (this.hasOwnProperty(o)) {
            var creategetter = (typeof this['get_' + o] !== 'function');
            var createsetter = (typeof this['set_' + o] !== 'function');
            (function () {
                var propname = o;
                if (creategetter) {
                    self['get_' + propname] = function () {
                        return self[propname];
                    };
                }
                if (createsetter) {
                    self['set_' + propname] = function (val) {
                        self[propname] = val;
                    };
                }
            })();
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top