Wie die Operatorüberladung verwendet werden sollte
Dieses Mal zeige ich Ihnen, wie Sie die Operatorüberladung verwenden und welche Vorsichtsmaßnahmen für die Verwendung der Operatorüberladung gelten. Das Folgende ist ein praktischer Fall, schauen wir uns das an.
Ich habe kürzlich Daten verarbeitet und einige Datenstrukturen wie Mat, Vektor, Punkt usw. angepasst. Ich muss die vier arithmetischen Operationen wie Addition, Subtraktion, usw. immer wieder definieren. Multiplikation und Division, Code Es scheint nicht sehr intuitiv zu sein, dass JavaScript keine Operatorüberladung hat, was eine Funktion wie C++ und C# ist. Es ist wirklich ärgerlich, deshalb möchte ich „das Land retten“, indem ich die Operatorüberladung automatisch implementiert Die Implementierungsidee ist eigentlich sehr einfach: Schreiben Sie einfach einen Interpreter. Zum Beispiel:
S = A + B (B - C.fun())/2 + D
übersetzt in
`S = ersetzen (ersetzen(A, '+', ersetzen(ersetzen(B,'',(ersetzen(B,'-',C.fun())))),'/',2),'+',D ) `
In der Ersetzungsfunktion rufen wir die entsprechende Operatorfunktion des Objekts auf. Der Ersetzungsfunktionscode lautet wie folgt:
/** * 转换方法 * @param a * @param op * @param b * @returns {*} * @private */ export function __replace__(a,op,b){ if(typeof(a) != 'object' && typeof(b) != 'object'){ return new Function('a','b','return a' + op + 'b')(a,b) } if(!Object.getPrototypeOf(a).isPrototypeOf(b) && Object.getPrototypeOf(b).isPrototypeOf(a)){ throw '不同类型的对象不能使用四则运算' } let target = null if (Object.getPrototypeOf(a).isPrototypeOf(b)) { target = new Function('return ' + b.__proto__.constructor.name)() } if (Object.getPrototypeOf(b).isPrototypeOf(a)) { target = new Function('return ' + a.__proto__.constructor.name)() } if (op == '+') { if (target.__add__ != undefined) { return target.__add__(a, b) }else { throw target.toString() +'\n未定义__add__方法' } }else if(op == '-') { if (target.__plus__ != undefined) { return target.__plus__(a, b) }else { throw target.toString() + '\n未定义__plus__方法' } }else if(op == '*') { if (target.__multiply__ != undefined) { return target.__multiply__(a, b) }else { throw target.toString() + '\n未定义__multiply__方法' } } else if (op == '/') { if (target.__pide__ != undefined) { return target.__pide__(a, b) }else { throw target.toString() + '\n未定义__pide__方法' } } else if (op == '%') { if (target.__mod__ != undefined) { return target.__mod__(a, b) }else { throw target.toString() + '\n未定义__mod__方法' } } else if(op == '.*') { if (target.__dot_multiply__ != undefined) { return target.__dot_multiply__(a, b) }else { throw target.toString() + '\n未定义__dot_multiply__方法' } } else if(op == './') { if (target.__dot_pide__ != undefined) { return target.__dot_pide__(a, b) }else { throw target.toString() + '\n未定义__dot_pide__方法' } } else if(op == '**') { if (target.__power__ != undefined) { return target.__power__(a, b) }else { throw target.toString() + '\n未定义__power__方法' } }else { throw op + '运算符无法识别' } }
Die Implementierung des Ersetzens ist sehr einfach zu viel erklären. Der wichtige Teil ist, wie der Code implementiert wird. Die Implementierung der vier arithmetischen Operationen beim Studium der Datenstruktur an der Hochschule ist die Grundlage dieser Übersetzung, mit geringfügigen Unterschieden. Beschreiben Sie kurz den Prozess:
1. Teilen Sie den Ausdruck, extrahieren Sie Variablen und Operatoren, um das Metaarray A zu erhalten.
2. Durchlaufen Sie das Metaarray
Wenn es sich bei den Elementen um Addition, Subtraktion und Multiplikation handelt und Division, dann entferne das vorherige Element vom Stapel und konvertiere es in „replace(last, Operator,
Wenn das Element „)“ ist, entferne das Element vom Stapel, spleiße es, bis es auf „(“ trifft, und drücke es in den Stapel. Beachten Sie hier '(' Gibt es einen Funktionsaufruf oder ein Ersetzen vor dem Element? Wenn es sich um einen Funktionsaufruf oder ein Ersetzen handelt, müssen Sie die Daten weiter nach vorne verschieben und die Ersetzungsfunktion schließen.
Wenn dies der Fall ist Ist ein allgemeines Element, prüfen Sie, ob das vorherige Element ersetzt wird, um die Ersetzungsfunktion zu schließen.
3 Erhalten Sie in Schritt 2 den kompilierten Ausdruck. 🎜>Implementieren Sie den Code gemäß dem obigen Prozess:
/** * 表达式转换工具方法 * @param code */ export function translate (code) { let data = [] let tmp_code = code.replace(/\s/g,'') let tmp = [] let vari = tmp_code.split(/["]+[^"]*["]+|[']+[^']*[']+|\*\*|\+|-|\*|\/|\(|\)|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|\}|=|%|\.\/|\.\*|,/g) let ops = tmp_code.match(/["]+[^"]*["]+|[']+[^']*[']+|\*\*|\+|-|\*|\/|\(|\)|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|\}|=|%|\.\/|\.\*|,/g) for (let i = 0,len = ops.length; i < len; i++) { if (vari[i] != '') { tmp.push(vari[i]) } if (ops[i] != '') { tmp.push(ops[i]) } } tmp.push(vari[ops.length]) for (let i = 0; i < tmp.length; i++){ let item = tmp[i] if(/\*\*|\+|-|\*|\/|%|\.\/|\.\*/.test(tmp[i])) { let top = data.pop() let trans = '__replace__(' + top + ',\'' + tmp[i] + '\',' data.push(trans) }else{ if (')' == tmp[i]) { let trans0 = tmp[i] let top0 = data.pop() while (top0 != '(') { trans0 = top0 + trans0 top0 = data.pop() } trans0 = top0 + trans0 let pre = data[data.length - 1] while(/[_\w]+[\.]?[_\w]+/.test(pre) && !/^__replace__\(/.test(pre) && pre != undefined) { pre = data.pop() trans0 = pre + trans0 pre = data[data.length - 1] } pre = data[data.length - 1] while(pre != undefined && /^__replace__\(/.test(pre)){ pre = data.pop() trans0 = pre + trans0 + ')' pre = data[data.length - 1] } data.push(trans0) }else { let pre = data[data.length - 1] let trans1 = tmp[i] while(pre != undefined && /^__replace__\(/.test(pre) && !/\*\*|\+|-|\*|\/|\(|\?|>[=]|<[=]|={2}|:|&{2}|\|{2}|\{|=|\}|%|\.\/|\.\*/.test(item) && !/^__replace__\(/.test(item)) { if(tmp[i + 1] == undefined){ pre = data.pop() trans1 = pre + trans1 + ')' break; }else{ pre = data.pop() trans1 = pre + trans1 + ')' pre = data[data.length - 1] } } data.push(trans1) } } } let result = '' data.forEach((value, key, own) => { result += value }) return result }
Der nächste Schritt besteht darin, den geschriebenen Code von unserem Übersetzer zu übersetzen Dies bedeutet, dass zwei Methoden erforderlich sind: Eine besteht darin, die Methodenattribute im Klassenkonstruktor neu zu definieren, und die andere besteht darin, den Code als Parameter an unsere benutzerdefinierte Methode zu übergeben Konstruktor:
export default class OOkay { constructor () { let protos = Object.getOwnPropertyNames(Object.getPrototypeOf(this)) protos.forEach((proto, key, own) => { if(proto != 'constructor'){ Object.defineProperty(this, proto, { value:new Function(translate_block(proto, this[proto].toString())).call(this) }) } }) } }
Wie Sie oben sehen können, verwenden wir Object.defineProperty, um es im Konstruktor neu zu definieren. Der Code lautet wie folgt:
/** * 类代码块转换工具 * @param name * @param block * @returns {string} */ export function translate_block (name , block) { let codes = block.split('\n') let reg = new RegExp('^' + name + '$') console.log(reg.source) codes[0] = codes[0].replace(name,'function') for(let i = 1; i < codes.length; i++) { if (codes[i].indexOf('//') != -1) { codes[i] = codes[i].substring(0,codes[i].indexOf('//')) } if(/\*\*|\+|-|\*|\/|%|\.\/|\.\*/g.test(codes[i])){ if (codes[i].indexOf('return ') != -1) { let ret_index = codes[i].indexOf('return ') + 7 codes[i] = codes[i].substring(0,ret_index) + translate(codes[i].substring(ret_index)) }else { let eq_index = codes[i].indexOf('=') + 1 codes[i] = codes[i].substring(0,eq_index) + translate(codes[i].substring(eq_index)) } } } return 'return ' + codes.join('\n') }
Für neue Klassen müssen wir nur die OOkay-Klasse erben, um Operatorüberladung in Klassen zu verwenden. Für Code, der von Nicht-OOkay-Klassen erbt, können wir die Injektion wie folgt verwenden:
/** * 非继承类的注入方法 * @param target */ static inject (target) { let protos = Object.getOwnPropertyNames(Object.getPrototypeOf(target)) protos.forEach((proto, key, own) => { if (proto != 'constructor') { Object.defineProperty(target, proto, { value:new Function(translate_block(proto, target[proto].toString())).call(target) }) } }) }
Für Code in Nicht-Klassen benötigen wir einen Container. Hier verwende ich zwei Methoden: Eine Möglichkeit, ookay-Skript zu verwenden, wie folgt:
Die andere besteht darin, den Code als Parameter an die Methode __$$__ zu übergeben, die den Code kompiliert und wie folgt ausführt:static __$__(fn) { if(!(fn instanceof Function)){ throw '参数错误' } (new Function(translate_block('function',fn.toString()))).call(window)() }
Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Bitte achten Sie auf andere verwandte Artikel auf der chinesischen PHP-Website.
Empfohlene Lektüre:
Vue+Nuxt.js ermöglicht serverseitiges RenderingAngular verwendet HMR-Code-ParsingDas obige ist der detaillierte Inhalt vonWie die Operatorüberladung verwendet werden sollte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



In Artikel werden JavaScript -Bibliotheken erstellt, veröffentlicht und aufrechterhalten und konzentriert sich auf Planung, Entwicklung, Testen, Dokumentation und Werbestrategien.

In dem Artikel werden Strategien zur Optimierung der JavaScript -Leistung in Browsern erörtert, wobei der Schwerpunkt auf die Reduzierung der Ausführungszeit und die Minimierung der Auswirkungen auf die Lastgeschwindigkeit der Seite wird.

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

In dem Artikel werden effektives JavaScript -Debuggen mithilfe von Browser -Entwickler -Tools, der Schwerpunkt auf dem Festlegen von Haltepunkten, der Konsole und der Analyse der Leistung erörtert.

Es gibt kein absolutes Gehalt für Python- und JavaScript -Entwickler, je nach Fähigkeiten und Branchenbedürfnissen. 1. Python kann mehr in Datenwissenschaft und maschinellem Lernen bezahlt werden. 2. JavaScript hat eine große Nachfrage in der Entwicklung von Front-End- und Full-Stack-Entwicklung, und sein Gehalt ist auch beträchtlich. 3. Einflussfaktoren umfassen Erfahrung, geografische Standort, Unternehmensgröße und spezifische Fähigkeiten.

In dem Artikel wird erläutert, wie Quellkarten zum Debuggen von JavaScript verwendet werden, indem er auf den ursprünglichen Code zurückgegeben wird. Es wird erläutert, dass Quellenkarten aktiviert, Breakpoints eingestellt und Tools wie Chrome Devtools und WebPack verwendet werden.

In diesem Tutorial wird erläutert, wie man mit Diagramm.js Kuchen-, Ring- und Bubble -Diagramme erstellt. Zuvor haben wir vier Chart -Arten von Charts gelernt. Erstellen Sie Kuchen- und Ringdiagramme Kreisdiagramme und Ringdiagramme sind ideal, um die Proportionen eines Ganzen anzuzeigen, das in verschiedene Teile unterteilt ist. Zum Beispiel kann ein Kreisdiagramm verwendet werden, um den Prozentsatz der männlichen Löwen, weiblichen Löwen und jungen Löwen in einer Safari oder den Prozentsatz der Stimmen zu zeigen, die verschiedene Kandidaten bei der Wahl erhalten. Kreisdiagramme eignen sich nur zum Vergleich einzelner Parameter oder Datensätze. Es ist zu beachten, dass das Kreisdiagramm keine Entitäten ohne Wert zeichnen kann, da der Winkel des Lüfters im Kreisdiagramm von der numerischen Größe des Datenpunkts abhängt. Dies bedeutet jede Entität ohne Anteil

Sobald Sie das Typscript-Tutorial für Einstiegsklasse gemeistert haben, sollten Sie in der Lage sein, Ihren eigenen Code in eine IDE zu schreiben, die TypeScript unterstützt und in JavaScript zusammenfasst. Dieses Tutorial wird in verschiedenen Datentypen in TypeScript eingetaucht. JavaScript hat sieben Datentypen: NULL, UNDEFINED, BOOLEAN, NUMMER, STRING, SYMBOL (durch ES6 eingeführt) und Objekt. TypeScript definiert mehr Typen auf dieser Grundlage, und dieses Tutorial wird alle ausführlich behandelt. Null -Datentyp Wie JavaScript, null in TypeScript
