2017-12-31 142 views
-1

Hallo Ich lerne gerade JavaScript für mein Projekt. Ich habe eine Frage zu diesem Funktionscode.JavaScript Extended Array funktioniert nicht wie erwartet ohne Fehlermeldung

function randomArr(){}; 
randomArr.prototype = new Array(); 
randomArr.prototype.getRandomValue = function(){ 
    var index = Math.floor(this.length * Math.random()); // return 0~1 
    return this[index]; 
} 

var arr = new randomArr('seoul', 'tokyo', 'beijing'); 
console.log(arr.getRandomValue()); 

Wenn ich diesen Code in Web-Browser ausgeführt wurde, ist die Ausgabe nur undefiniert.

+0

Ihre 'randomArr' Funktion tut nichts mit ihren Argumenten, der Wert swill wird einfach verworfen. – Bergi

+0

Sie können 'Array' nicht ableiten, ohne die' class'-Syntax zu verwenden. Das heißt, Subclassing ist wahrscheinlich nicht der beste Ansatz für eine "zufällige" Auswahl, schreiben Sie einfach eine normale Funktion, an die Sie ein normales Array als Argument übergeben. – Bergi

Antwort

2

Für mich ist es das Hinzufügen besser, um diese Funktion Array-Typ:

Array.prototype.getRandomValue = function(){ 
    var index = Math.floor(this.length * Math.random()); // return 0~1 
    return this[index]; 
} 

Array arr = new Array('seoul', 'tokyo', 'beijing'); 
console.log(arr.getRandomValue()); 

Werfen Sie einen Blick auf diese interessante Erklärung:https://coderwall.com/p/h4xm0w/why-never-use-new-array-in-javascript

Nach diesem Link, sollten Sie Arrays verwenden, wie folgt :

var arr = ['seoul', 'tokyo', 'beijing']; 
console.log(arr.getRandomValue()); 

Hoffe das hilft!

1

Einer der großen Vorteile von ES6-Klassen ist, dass sie "exotische" Klassen wie Arrays ableiten können. Es ist möglich, ältere Versionen von Javascript in Subklassen-Arrays zu tricksen, aber es lohnt sich nicht, das hier zu erklären. Ein weiteres Problem ist, dass Sie ein extrem schlechtes Muster von Unterklassen für Pre-ES6-Javascript verwenden, um die Basisklasse zu instanziieren und eine Instanz der Basisklasse zu der Prototypkette Ihrer neuen Klasse hinzuzufügen, anstatt sie zuerst zu kleben. Dies ist, was Typescript unter der Haube tut, aber es macht einige schreckliche Annahmen. In Ihrem Fall wurde der Array-Konstruktor bereits aufgerufen, lange bevor Sie Ihre Liste von Städten zur Verfügung gestellt haben, und Sie haben ein leeres Array erstellt, so dass dies fehlgeschlagen wäre, selbst wenn Sie solche Arrays ableiten könnten.

Dieser Code ist der moderne Weg, dies zu tun. Ich habe den zusätzlichen Schritt unternommen, das in Eleazars Link aufgeworfene Problem anzugehen, indem ich die Argumente des Konstruktors nicht direkt an den Array-Basiskonstruktor weitergab, sondern stattdessen den Basiskonstruktor ein leeres Array erstellen ließ und dann die Werte dorthin drängte.

class randomArr extends Array{ 
    constructor(..._items){ 
     super() 
     _items.forEach(_=>this.push(_)) 
    } 
    getRandomValue(){ 
     const index=Math.floor(this.length*Math.random()) 
     return this[index] 
    } 
} 

let arr=new randomArr('seoul', 'tokyo', 'beijing') 
console.log(arr.getRandomValue()) 

Trotz Eleazers Ratschlag, würde ich vermeiden, Kernprototypen mit benannten Eigenschaften hinzuzufügen. Ich habe festgestellt, dass die Symboleigenschaften für diesen Zweck perfekt sind. Hier ist, was das aussehen würde:

const getRandomValue=Symbol() 
Reflect.defineProperty(
    Array.prototype, 
    getRandomValue, 
    { 
     value(){ 
      const index=Math.floor(this.length*Math.random()) 
      return this[index] 
     } 
    } 
) 

let arr=['seoul', 'tokyo', 'beijing'] 
console.log(arr[getRandomValue]()) 

Der Vorteil der Symbol Route ist, dass Sie garantiert nicht Namenskollisionen mit einer anderen Bibliothek hat auch den Array-Prototyp erstreckt.

0

Dies ist ein Verfahren unter Verwendung Prototypkette und die Vermeidung von Additionsverfahren direkt zu Array.prototype.

function randomArr() {            
Array.call(this);              
    for (x in arguments) {         
    this.push(arguments[x]);           
    }                   
}               

randomArr.prototype = Object.create(Array.prototype); 
randomArr.prototype.constructor = randomArr; 

randomArr.prototype.getRandomValue = function(){       
var index = Math.floor(this.length * Math.random()); // return 0~1  
return this[index];           
}                   

var arr = new randomArr('seoul', 'tokyo', 'beijing');  
alert(arr.splice(1,1)); // works as desired  
alert(arr.getRandomValue()); // works fine 
Verwandte Themen