التحميل الزائد على العوامل الحسابية في جافا سكريبت؟

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

  •  06-07-2019
  •  | 
  •  

سؤال

هذه هي أفضل طريقة يمكنني التفكير بها لصياغة هذا السؤال، بالنظر إلى تعريف "الفئة" لجافا سكريبت:

var Quota = function(hours, minutes, seconds){
    if (arguments.length === 3) {
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;

        this.totalMilliseconds = Math.floor((hours * 3600000)) + Math.floor((minutes * 60000)) + Math.floor((seconds * 1000));
    }
    else if (arguments.length === 1) {
        this.totalMilliseconds = hours;

        this.hours = Math.floor(this.totalMilliseconds / 3600000);
        this.minutes = Math.floor((this.totalMilliseconds % 3600000) / 60000);
        this.seconds = Math.floor(((this.totalMilliseconds % 3600000) % 60000) / 1000);
    }

    this.padL = function(val){
        return (val.toString().length === 1) ? "0" + val : val;
    };

    this.toString = function(){
        return this.padL(this.hours) + ":" + this.padL(this.minutes) + ":" + this.padL(this.seconds);
    };

    this.valueOf = function(){
        return this.totalMilliseconds;
    };
};

ورمز إعداد الاختبار التالي:

var q1 = new Quota(23, 58, 50);
var q2 = new Quota(0, 1, 0);
var q3 = new Quota(0, 0, 10);

console.log("Quota 01 is " + q1.toString());    // Prints "Quota 01 is 23:58:50"
console.log("Quota 02 is " + q2.toString());    // Prints "Quota 02 is 00:01:00"
console.log("Quota 03 is " + q3.toString());    // Prints "Quota 03 is 00:00:10"

هل هناك أي طريقة للخلق ضمنا q4 ك Quota كائن باستخدام عامل الإضافة على النحو التالي ...

var q4 = q1 + q2 + q3;
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 86400000"

بدلاً من اللجوء إلى...

var q4 = new Quota(q1 + q2 + q3);
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 24:00:00"

إذا لم يكن الأمر كذلك، فما هي توصيات أفضل الممارسات في هذا المجال لجعل كائنات JavaScript رقمية مخصصة قابلة للتركيب عبر العوامل الحسابية؟

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

المحلول

وكما بقدر ما أنا على علم، جافا سكريبت (على الأقل كما كان موجودا الآن) لا يدعم مشغل الحمولة الزائدة.

وأفضل ما يمكن أن توحي هو أسلوب فئة لصنع الأشياء حصة جديدة من عدة أشخاص آخرين. وإليك مثال سريع لما أعنيه:

// define an example "class"
var NumClass = function(value){
    this.value = value;
}
NumClass.prototype.toInteger = function(){
    return this.value;
}

// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
    var newValue = 0;
    for (var i=0; i<arguments.length; i++){
        newValue += arguments[i].toInteger();
    }
    return new this(newValue)
}

واستخدامه مثل:

var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);

var combined = NumClass.createFromObjects(n1, n2, n3);

نصائح أخرى

للأسف لا.

لfallbacks، إذا كنت ترتيب القيم المقابل، هل يمكن استخدام طريقة تسلسل

var q4 = q1.plus(p2).plus(q3);

ولأن الجميع صوت أسفل جوابي أخرى أنا أرغب في وظيفة دليل على كود المفهوم الذي يفعل في العمل الواقع على النحو المنشود.

تم اختبار هذا في الكروم وIE.

//Operator Overloading

var myClass = function () {

//Privates

var intValue = Number(0),
    stringValue = String('');

//Publics
this.valueOf = function () {
    if (this instanceof myClass) return intValue;
    return stringValue;
}

this.cast = function (type, call) {
    if (!type) return;
    if (!call) return type.bind(this);
    return call.bind(new type(this)).call(this);
}

}

//Derived class
var anotherClass = function () {

//Store the base reference
this.constructor = myClass.apply(this);

var myString = 'Test',
    myInt = 1;

this.valueOf = function () {
    if (this instanceof myClass) return myInt;
    return myString;
}

}


//Tests

var test = new myClass(),
anotherTest = new anotherClass(),
composed = test + anotherTest,
yaComposed = test.cast(Number, function () {
    return this + anotherTest
}),
yaCComposed = anotherTest.cast(Number, function () {
    return this + test;
}),
t = test.cast(anotherClass, function () {
    return this + anotherTest
}),
tt = anotherTest.cast(myClass, function () {
    return this + test;
});

debugger;

إذا شخص ما من شأنه أن يكون ذلك النوع لإعطاء شرحا تقنيا لماذا هذا ليس جيدا بما فيه الكفاية وسأكون سعيدا لسماع ذلك!

واقتراح الثاني:

var q4 = Quota.add(q1, q2, q3);

وأنا في الآونة الأخيرة جاء بناء على هذه المادة: HTTP: //www.2ality كوم / 2011/12 / همية المشغلين overloading.html .

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

ويمكنك تحويل ضمنيا إلى عدد صحيح أو سلسلة، الأشياء الخاصة بك

يتم تحويل

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

و1.- اتصل valueOf (). إذا كانت النتيجة هي بدائية (وليس كائن) ثم استخدامه وتحويله إلى رقم.

و2.- وإلا، استدعاء toString (). إذا كانت النتيجة هي بدائية، واستخدامها وتحويلها إلى رقم.

و3.- وإلا، ورمي TypeError. مثال للخطوة 1:

<اقتباس فقرة>   

و3 * {valueOf: وظيفة () {عودة (5)}}

إذا يحول جافا سكريبت لسلسلة الخطوات 1 و 2 وتبادلت: toString () وحاول أولا، valueOf () الثانية

http://www.2ality.com/2013/04/ هوس-ضمنا-conversion.html

وPaper.js يفعل ذلك، على سبيل المثال مع إضافة نقطة ( مستندات ):

var point = new Point(5, 10);
var result = point + 20;
console.log(result); // {x: 25, y: 30}

ولكن من يفعل ذلك باستخدام محلل .

وأنا لست متأكدا لماذا يستمر الناس في الإجابة على هذا السؤال مع لا!

وهناك على الاطلاق طريقة التي سوف أتناول مع نصي صغيرة جدا الذي لديك لا يجب أن تكون جون ريسيغ لفهم ...

وقبل أن أفعل ذلك وسوف أذكر أيضا أنه في جافا سكريبت الطريق من شأنه أن منشئ الخاص عملت هي عن طريق التحقق من صفائف أو بالتكرار وحجج "الحرفي.

ومنها مثلا. في بلدي منشئ بلادي 'الفئة' أود أن تكرار وarugments، وتحديد نوع arugments الكامنة ومعالجته بذكاء.

وهذا يعني أنه إذا كنت تمرير صفيف أود أن تكرار وarugments العثور على مجموعة وثم تكرار مجموعة للقيام مزيد من المعالجة تبعا لنوع العنصر في المصفوفة.

ومنها مثلا. -> someClass الجديد ([instanceA، instanceB، instanceC])

ولكن يا رفاق يبحثون عن مزيد من "C" نهج أسلوب إلى الحمولة الزائدة المشغل الذي يمكن فعلا أن يتحقق على عكس الاعتقاد populare.

وهنا هي فئة التي أشرت التي تم إنشاؤها باستخدام موتولز التي لا المشغل شرف الحمولة الزائدة. في جافا سكريبت سهل القديمة كنت مجرد استخدام نفس الأسلوب toString إرفاقه فقط على النموذج الدرجة مباشرة.

وسبب اهتمامي الرئيسي لعرض هذا النهج هو بسبب النص I باستمرار قراءة التي تنص على هذه الوظيفة هو "المستحيل" لمحاكاة. لا شيء مستحيل فقط من الصعب sufficently وأنا سيتم عرض هذا أدناه ...

 //////

debugger;

//Make a counter to prove I am overloading operators
var counter = 0;

//A test class with a overriden operator
var TestClass = new Class({
    Implements: [Options, Events],
    stringValue: 'test',
    intValue: 0,
    initialize: function (options) {
        if (options && options instanceof TestClass) {
            //Copy or compose
            this.intValue += options.intValue;
            this.stringValue += options.stringValue;
        } else {
            this.intValue = counter++;
        }
    },
    toString: function () {
        debugger;
        //Make a reference to myself
        var self = this;
        //Determine the logic which will handle overloads for like instances
        if (self instanceof TestClass) return self.intValue;
        //If this is not a like instance or we do not want to overload return the string value or a default.
        return self.stringValue;
    }
});

//Export the class
window.TestClass = TestClass;

//make an instance
var myTest = new TestClass();

//make another instance
var other = new TestClass();

//Make a value which is composed of the two utilizing the operator overload
var composed = myTest + other;

//Make a value which is composed of a string and a single value
var stringTest = '' + myTest;

//////

لوحظ العرض الأخير من هذه التسميات في صفحة وثائق XDate في: http://arshaw.com/xdate/

في هذه الحالة أعتقد أنه كان في الواقع حتى ياسير، وقال انه يمكن أن تستخدم النموذج الأولي للكائن التاريخ و لتحقيق الشيء نفسه.

وعلى الرغم من ذلك الطريقة التي ذكرتها كمثال والتي ينبغي أن تصوير هذا النمط من استغلال للآخرين.

وتحرير:

ولدي التنفيذ الكامل هنا:

http://netjs.codeplex.com/

وجنبا إلى جنب مع غيرها من الأشياء الجيدة.

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

  • يجب تمرير نتائج الحساب إلى كائن جديد، لذلك بدلاً من (p1 + p2 + p3) عليك القيام بنقطة جديدة (p1 + p2 + p3)، (نظرًا لأن الكائن المحدد من قبل المستخدم يسمى "نقطة").

  • يتم فقط دعم + و- و* و/، أما العامل الحسابي الخامس % فهو غير مدعوم.لن يعمل الإكراه على السلاسل ("+p1) والمقارنات (p1 == p2) كما هو متوقع.وينبغي بناء دوال جديدة لهذه الأغراض إذا لزم الأمر، مثل (p1.val == p2.val).

  • وأخيرًا، تزداد الموارد الحسابية اللازمة لحساب الإجابة بشكل تربيعي مع عدد الحدود.لذلك، يُسمح بـ 6 مصطلحات فقط في سلسلة حسابية واحدة لكل افتراضي (على الرغم من إمكانية زيادة هذا العدد).بالنسبة لسلاسل العمليات الحسابية الأطول من ذلك، قم بتقسيم العمليات الحسابية، مثل:نقطة جديدة(نقطة جديدة(p1 + p2 + p3 + p4 + p5 + p6) + نقطة جديدة(p7 + p8 + p9 + p10 + p11 + p12))

ال صفحة جيثب.

وبالإضافة إلى ما سبق أن قيل: تجاوز .valueOf () قد تساعد على إنتاج قوية جدا المشغل الحمولة الزائدة. في إثبات صحة مفهوم Fingers.js ليب يمكنك إضافة المستمعين الحدث في الاسلوب .NET:

function hi() { console.log("hi") }
function stackoverflow() { console.log("stackoverflow") }
function bye() { console.log("bye") }

on(yourButton).click += hi + stackoverflow;
on(yourButton).click -= hi - bye;

والفكرة الأساسية هي استبدال مؤقتا valueOf عندما على () ويسمى:

const extendedValueOf = function () {
    if (handlers.length >= 16) {
        throw new Error("Max 16 functions can be added/removed at once using on(..) syntax");
    }

    handlers.push(this); // save current function

    return 1 << ((handlers.length - 1) * 2); // serialize it as a number.
};

وعدد عاد يمكن بعد ذلك نزع تسلسل ظهر في وظيفة باستخدام معالجات مجموعة. ما هو أكثر من ذلك انها القيم استخراج الشيء ممكن من القيمة النهائية (func1 + func2 - func3). بذلك على نحو فعال هل يمكن أن نفهم ما هي الوظائف التي أضيفت، وما هي الوظائف أزيلت

ويمكنك التحقق من المصدر على جيثب واللعب مع <لأ href = "HTTP: / /filimanjaro.com/fingers/demo.html "يختلط =" نوفولو "> عرض هنا .

وجود شرح شامل في هذا <وأ href = "http://filimanjaro.com/2012/operators-overloading-in-as3-javascript-too-٪E2٪80٪93-workaround/" يختلط = "نوفولو" > المقالة (انها لAS3، صعبة منذ انها ecmascript أنها ستعمل لJS إما).

لبعض حالات الاستخدام محدودة يمكنك الحصول على مشغل "الحمولة الزائدة" الآثار:

function MyIntyClass() {
    this.valueOf = function() { return Math.random(); }
}
var a = new MyIntyClass();
var b = new MyIntyClass();
a < b
false

a + b
0.6169137847609818

[a, b].sort() // O(n^2) ?
[myClass, myClass]

function MyStringyClass() {
    this.valueOf = function() { return 'abcdefg'[Math.floor(Math.random()*7)]; }
}
c = new MyStringyClass();
'Hello, ' + c + '!'
Hello, f!

ورمز أعلاه مجاني للاستخدام تحت رخصة MIT. YMMV.

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