Les traits cachés de JavaScript? [fermé]

Quelles "caractéristiques cachées" de JavaScript pensez-vous que chaque programmeur devrait savoir?

Après avoir vu l'excellente qualité des réponses aux questions suivantes, j'ai pensé qu'il était temps de lui demander pour le JavaScript.

même si JavaScript est sans doute le langage Client le plus important à L'heure actuelle (demandez à Google), il est surprenant comment peu la plupart des développeurs web apprécient la puissance qu'il est vraiment.

312
demandé sur Binoj Antony 2008-09-14 07:12:50
la source

30 ответов

Vous n'avez pas besoin de définir les paramètres d'une fonction. Vous pouvez simplement utiliser l'objet de type tableau arguments de la fonction.

function sum() {
    var retval = 0;
    for (var i = 0, len = arguments.length; i < len; ++i) {
        retval += arguments[i];
    }
    return retval;
}

sum(1, 2, 3) // returns 6
373
répondu Mark Cidade 2011-01-14 14:38:57
la source

je pourrais citer la plupart de L'excellent Livre de Douglas Crockford JavaScript: Les Bonnes Parties .

mais je n'en prendrai qu'un pour vous, utilisez toujours === et !== au lieu de == et !=

alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true

== n'est pas transitive. Si vous utilisez === il donnerait false pour toutes ces déclarations comme prévu.

204
répondu Martin Clarke 2012-02-06 17:51:31
la source

fonctions sont des citoyens de première classe en JavaScript:

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

les techniques de programmation fonctionnelle peuvent être utilisées pour écrire l'élégant javascript .

en particulier, les fonctions peuvent être passées comme paramètres, par exemple tableau.filter () accepte un callback:

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

vous pouvez également déclarer une fonction "privée" qui n'existe que dans le cadre d'une fonction spécifique:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}
189
répondu Gulzar Nazim 2009-09-23 00:29:14
la source

vous pouvez utiliser l'opérateur dans pour vérifier si une clé existe dans un objet:

var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true

si vous trouvez l'objet littéral trop laid, vous pouvez le combiner avec la fonction sans paramètres conseil:

function list()
 { var x = {};
   for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
   return x
 }

 5 in list(1,2,3,4,5) //true
162
répondu Mark Cidade 2010-11-24 05:16:47
la source

Attribution des valeurs par défaut pour les variables

vous pouvez utiliser la logique ou l'opérateur || dans une expression d'assignation pour fournir une valeur par défaut:

var a = b || c;

la variable a obtiendra la valeur de c seulement si b est falsy (si est null , false , undefined , 0 , empty string , ou NaN ), sinon a aura la valeur de b .

c'est souvent utile dans les fonctions, quand vous voulez donner une valeur par défaut à un argument dans le cas où n'est pas fourni:

function example(arg1) {
  arg1 || (arg1 = 'default value');
}

Exemple IE secours dans les gestionnaires d'événements:

function onClick(e) {
    e || (e = window.event);
}

n'ont pas fait partie de la spécification jusqu'à ECMAScript 5e édition :

Le debugger déclaration

décrit dans: § 12.15 la déclaration du débogueur

cette instruction vous permet de mettre breakpoints programmatically dans votre code juste par:

// ...
debugger;
// ...

si un débogueur est présent ou actif, il va le faire casser immédiatement, sur cette ligne.

Sinon, si le débogueur n'est pas présent ou actif, cette déclaration n'a aucun effet observable.

Multiline littéraux de Chaîne

Décrites dans: § 7.8.4 Littéraux de Chaîne

var str = "This is a \
really, really \
long line!";

vous devez être prudent parce que le personnage à côté du \ doit être un terminateur de ligne, si vous avez un espace après le \ par exemple, le code sera regarder exactement le même, mais il soulèvera un SyntaxError .

153
répondu CMS 2011-09-28 18:44:41
la source

JavaScript n'a pas de block scope (mais il a fermeture donc appelons-le même?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2
145
répondu Eugene Yokota 2008-09-14 11:02:15
la source

vous pouvez accéder aux propriétés des objets avec [] au lieu de .

cela vous permet de chercher une propriété correspondant à une variable.

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

vous pouvez également utiliser ceci pour obtenir/définir des propriétés d'objet dont le nom n'est pas un identifiant légal.

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

certaines personnes ne le savent pas et finissent par utiliser eval () comme ceci, qui est un vraiment mauvais idée :

var propname = "a";
var a = eval("obj." + propname);

c'est plus difficile à lire, plus difficile de trouver des erreurs dans (ne peut pas utiliser jslint), plus lent à exécuter, et peut conduire à des exploits XSS.

144
répondu Patrick 2010-06-07 07:14:24
la source

si vous Googlez pour une référence JavaScript décente sur un sujet donné, inclure le mot-clé" mdc " dans votre requête et vos premiers résultats seront à partir du Mozilla Developer Center. Je n'ai pas de références ou de livres hors ligne avec moi. J'utilise toujours le mot clé" mdc " pour obtenir directement ce que je cherche. Par exemple:

Google: javascript tableau de tri mdc

(dans la plupart des cas, vous pouvez omettre "javascript")

mise à Jour: Mozilla Developer Centre a été renommé Mozilla Developer Réseau . Le truc du mot-clé" mdc "fonctionne toujours, mais assez tôt nous pourrions avoir à commencer à utiliser" mdn "à la place .

144
répondu Ates Goral 2010-12-15 20:41:53
la source

Peut-être un peu évident pour certains...

Installer Firebug et l'utilisation de la console.log("bonjour"). Tellement mieux qu'à l'aide de random alert();'s dont je me souviens, fait beaucoup il y a quelques années.

143
répondu qui 2009-09-23 00:30:37
la source

Méthodes Privées

Un objet peut avoir des méthodes privées.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // A private method only visible from within this constructor
    function calcFullName() {
       return firstName + " " + lastName;    
    }

    // A public method available to everyone
    this.sayHello = function () {
        alert(calcFullName());
    }
}

//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();

// This fails since the method is not visible from this scope
alert(person1.calcFullName());
120
répondu Allain Lalonde 2008-09-14 08:40:52
la source

également mentionné dans "Javascript: the Good Parts" de Crockford:

parseInt() est dangereux. Si vous lui passez une corde sans l'informer de la base appropriée, il peut retourner des nombres inattendus. Par exemple parseInt('010') renvoie 8, Pas 10. Passer une base à parseInt lui permet de fonctionner correctement:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.
99
répondu 2 revs, 2 users 91%bluefish101 2010-06-07 07:18:52
la source

les fonctions sont des objets et peuvent donc avoir des propriétés.

fn = function(x) {
   // ...
}

fn.foo = 1;

fn.next = function(y) {
  //
}
97
répondu VolkerK 2008-09-14 14:48:32
la source

je dirais des fonctions auto-exécutables.

(function() { alert("hi there");})();

parce que Javascript n'a pas de champ d'application de bloc , vous pouvez utiliser une fonction d'auto-exécution si vous voulez définir des variables locales:

(function() {
  var myvar = 2;
  alert(myvar);
})();

ici, myvar est n'interfère pas avec ou pollue la portée globale, et disparaît lorsque la fonction se termine.

91
répondu thomasrutter 2017-05-23 15:18:07
la source

savent combien de paramètres sont attendus par une fonction

function add_nums(num1, num2, num3 ){
    return num1 + num2 + num3;
}
add_nums.length // 3 is the number of parameters expected.

savent combien de paramètres sont reçus par la fonction

function add_many_nums(){
    return arguments.length;
}    
add_many_nums(2,1,122,12,21,89); //returns 6
83
répondu pramodc84 2010-08-06 07:50:08
la source

Voici quelques choses intéressantes:

  • comparer NaN avec n'importe quoi (même NaN ) est toujours faux, qui inclut == , < et > .
  • NaN N'est pas un nombre mais si vous demandez le type, il renvoie un nombre.
  • Array.sort peut prendre une fonction de comparaison et est appelé par un pilote de type quicksort (dépend de l'implémentation).
  • expression Régulière "constantes" peut maintenir l'état, comme la dernière chose qu'ils correspondaient.
  • certaines versions de JavaScript vous permettent d'accéder "151970920" , , membres sur une regex.
  • null ne ressemble à rien d'autre. Il n'est ni un objet, un booléen, un nombre, une chaîne de caractères, ni undefined . C'est un peu comme un "autre" undefined . (Note: typeof null == "object" )
  • In le contexte extérieur, this , donne l'objet [Global], qui est par ailleurs impénétrable.
  • déclarer une variable avec var , au lieu de simplement compter sur la déclaration automatique de la variable donne à l'exécution une réelle chance d'optimiser l'accès à cette variable
  • la construction with détruira de telles optimzations
  • les noms de variables peuvent contenir des caractères Unicode.
  • JavaScript les expressions régulières ne sont pas réellement régulier. Ils sont basés sur les regexs de Perl, et il est possible de construire des expressions avec des lookheads qui prennent un temps très, très long à évaluer.
  • Les blocs
  • peuvent être étiquetés et utilisés comme cibles de break . Les boucles peuvent être étiquetées et utilisées comme cible de continue .
  • Les matrices
  • ne sont pas rares. Définir le 1000e élément d'un tableau vide par ailleurs devrait le remplir avec undefined . (dépend de la la mise en œuvre)
  • if (new Boolean(false)) {...} exécutera le {...} bloc
  • Les moteurs D'expressions régulières
  • Javascript sont spécifiques à la mise en œuvre: par exemple, il est possible d'écrire des expressions régulières "Non portables".

[mise à jour un peu en réponse à de bons commentaires; s'il vous plaît voir les commentaires]

79
répondu David Leonard 2011-06-15 18:39:03
la source

je sais que je suis en retard à la fête, mais je ne peux pas croire que l'utilité de l'opérateur + n'a pas été mentionnée au-delà de"convertissez n'importe quoi en un nombre". Peut-être que c'est à quel point c'est bien caché?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

bien sûr, vous pouvez faire tout cela en utilisant Number() à la place, mais l'opérateur + est tellement plus joli!

vous pouvez également définir une valeur numérique de retour pour un objet en remplaçant le prototype valueOf() méthode. Toute conversion de nombre effectuée sur cet objet ne donnera pas NaN , mais la valeur de retour de la méthode valueOf() :

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;
77
répondu Andy E 2010-09-07 14:17:51
la source

méthodes D'Extension en JavaScript " via la propriété prototype.

Array.prototype.contains = function(value) {  
    for (var i = 0; i < this.length; i++) {  
        if (this[i] == value) return true;  
    }  
    return false;  
}

ceci ajoutera une méthode contains à tous les objets Array . Vous pouvez appeler cette méthode en utilisant cette syntaxe

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");
75
répondu spoon16 2009-04-26 06:44:18
la source

pour supprimer correctement une propriété d'un objet, vous devriez supprimer la propriété au lieu de simplement la définir à Non défini :

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

La propriété prop2 sera toujours une partie de l'itération. Si vous voulez vous débarrasser complètement de prop2 , vous devriez plutôt faire:

delete obj.prop2;

le bien prop2 ne fera plus apparence lorsque vous itérez à travers les propriétés.

60
répondu Ates Goral 2008-10-01 05:05:45
la source

with .

Il est rarement utilisé, et franchement, rarement utile... Mais, dans des circonstances limitées, elle a son utilité.

par exemple: les littérales d'objet sont assez pratiques pour configurer rapidement des propriétés sur un nouveau . Mais que faire si vous avez besoin de changer la moitié des propriétés sur un objet existant?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm souligne que cela peut être quelque peu dangereux: si l'objet utilisé comme contexte ne ont l'une des propriétés étant assignée, il sera résolu dans la portée externe, créant éventuellement ou écrasant une variable globale. C'est particulièrement dangereux si vous êtes habitué à écrire du code pour travailler avec des objets dont les propriétés avec des valeurs par défaut ou vides ne sont pas définies:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

par conséquent, il est probablement une bonne idée d'éviter l'utilisation de la déclaration with pour une telle cession.

Voir aussi: y a-t-il des utilisations légitimes de la déclaration "avec" de JavaScript?

57
répondu Shog9 2017-05-23 15:26:11
la source
Les méthodes (ou fonctions)

peuvent être appelées sur des objets qui ne sont pas du type de ceux avec lesquels elles ont été conçues. C'est génial d'appeler des méthodes natives (rapides) sur des objets personnalisés.

var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });

ce code s'écrase parce que listNodes n'est pas un Array

Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);

ce code fonctionne parce que listNodes définit suffisamment de propriétés de type tableau (longueur, [] opérateur) pour être utilisé par sort() .

51
répondu Vincent Robert 2008-09-20 01:02:48
la source

prototypal inheritance (popularisé par Douglas Crockford) révolutionne complètement la façon dont vous pensez à des charges de choses en Javascript.

Object.beget = (function(Function){
    return function(Object){
        Function.prototype = Object;
        return new Function;
    }
})(function(){});

C'est un tueur! Pitié, presque personne ne l'utilise.

il vous permet de" générer " de nouvelles instances de n'importe quel objet, de les étendre, tout en maintenant un lien d'héritage (live) prototypique à leurs autres propriétés. Exemple:

var A = {
  foo : 'greetings'
};  
var B = Object.beget(A);

alert(B.foo);     // 'greetings'

// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo);     // 'hello'

A.bar = 'world';
alert(B.bar);     // 'world'


// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo);     // 'hello'

B.bar = 'universe';
alert(A.bar);     // 'world'
43
répondu Már Örlygsson 2009-12-28 18:42:23
la source

certains appelleraient cela une question de goût, mais:

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

La trinary de l'opérateur peuvent être enchaînés à agir comme Scheme (cond ...):

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

peut s'écrire comme...

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

c'est très "fonctionnel", car il branche votre code sans effets secondaires. Donc au lieu de:

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

vous pouvez écrire:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

fonctionne bien avec la récursion, aussi :)

42
répondu Andrey Fedorov 2010-03-22 22:57:16
la source
Les nombres

sont aussi des objets. Donc vous pouvez faire des trucs cool comme:

// convert to base 2
(5).toString(2) // returns "101"

// provide built in iteration
Number.prototype.times = function(funct){
  if(typeof funct === 'function') {
    for(var i = 0;i < Math.floor(this);i++) {
      funct(i);
    }
  }
  return this;
}


(5).times(function(i){
  string += i+" ";
});
// string now equals "0 1 2 3 4 "

var x = 1000;

x.times(function(i){
  document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document
41
répondu Zach 2008-09-21 00:56:04
la source

Que Diriez-vous de fermetures en JavaScript (similaire aux méthodes anonymes dans C# v2.0+). Vous pouvez créer une fonction qui crée une fonction ou d'une "expression".

exemple de fermetures :

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);
33
répondu Tyler 2010-01-29 20:58:10
la source

vous pouvez également étendre (hériter) les classes et outrepasser les propriétés/méthodes en utilisant la chaîne prototype spoon16 fait allusion.

dans l'exemple suivant, nous créons une classe Pet et définissons certaines propriétés. Nous annulons aussi le .méthode toString () héritée de L'objet.

après cela, nous créons une classe de chien qui étend Pet et l'emporte sur le .méthode toString() encore une fois modifier son comportement (polymorphisme). En outre, nous ajoutons quelques autres propriétés à la classe enfant.

après cela, nous vérifions la chaîne héréditaire pour montrer que le chien est encore de type chien, de type animal de compagnie, et de type Objet.

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

les deux réponses à cette question étaient des codes modifiés d'un grand article MSDN par Ray Djajadinata.

32
répondu Tyler 2010-05-01 17:13:58
la source

vous pouvez attraper des exceptions selon leur type. Tiré de MDC :

try {
   myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
   // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
   // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
   // statements to handle EvalError exceptions
} catch (e) {
   // statements to handle any unspecified exceptions
   logMyErrors(e); // pass exception object to error handler
}

NOTE: les clauses de capture conditionnelle sont des extensions Netscape (et donc Mozilla/Firefox) qui ne font pas partie de la spécification ECMAScript et ne peuvent donc pas être utilisées sauf sur des navigateurs particuliers.

31
répondu Ionuț G. Stan 2010-03-23 16:29:21
la source

sur le dessus de ma tête...

fonctions

arguments.callee fait référence à la fonction qui héberge la variable "arguments", de sorte qu'elle peut être utilisée pour remplacer les fonctions anonymes:

var recurse = function() {
  if (condition) arguments.callee(); //calls recurse() again
}

C'est utile si vous voulez faire quelque chose comme ceci:

//do something to all array items within an array recursively
myArray.forEach(function(item) {
  if (item instanceof Array) item.forEach(arguments.callee)
  else {/*...*/}
})

Objets

une chose intéressante au sujet des membres d'objet: ils peuvent avoir n'importe quelle chaîne comme leurs noms:

//these are normal object members
var obj = {
  a : function() {},
  b : function() {}
}
//but we can do this too
var rules = {
  ".layout .widget" : function(element) {},
  "a[href]" : function(element) {}
}
/* 
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
  var elements = document.querySelectorAll(rules[item]);
  for (var e, i = 0; e = elements[i++];) rules[item](e);
}

cordes

de la Chaîne.split peut prendre des expressions régulières comme paramètres:

"hello world   with  spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]

de la Chaîne.remplacer peut prendre une expression régulière comme paramètre de recherche et une fonction comme paramètre de remplacement:

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"
31
répondu Leo 2010-09-15 09:59:45
la source

vous pouvez utiliser des objets à la place des commutateurs la plupart du temps.

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(getInnerText).join(""),
        object:getInnerText(o["childNodes"])
    }[typeis(o)];
}

mise à jour: si vous êtes préoccupé par le fait que les cas évalués à l'avance sont inefficaces (pourquoi vous inquiétez-vous de l'efficacité si tôt dans la conception du programme?? ensuite, vous pouvez faire quelque chose comme ceci:

function getInnerText(o){
    return o === null? null : {
        string: function() { return o;},
        array: function() { return o.map(getInnerText).join(""); },
        object: function () { return getInnerText(o["childNodes"]; ) }
    }[typeis(o)]();
}

il est plus onéreux de taper (ou de lire) qu'un interrupteur ou un objet, mais il préserve les avantages d'utiliser un objet au lieu d'un switch, détaillé dans la section des commentaires ci-dessous. Ce style rend aussi plus simple de le transformer en une véritable" classe " une fois qu'il aura suffisamment grandi.

update2: avec des propositions de syntaxe extensions pour ES.ensuite, cela devient

let getInnerText = o -> ({
    string: o -> o,
    array: o -> o.map(getInnerText).join(""),
    object: o -> getInnerText(o["childNodes"])
}[ typeis o ] || (->null) )(o);
29
répondu Breton 2011-10-08 10:46:47
la source

assurez-vous d'utiliser la méthode hasOwnProperty lorsque vous itérez les propriétés d'un objet:

for (p in anObject) {
    if (anObject.hasOwnProperty(p)) {
        //Do stuff with p here
    }
}

Ceci est fait de sorte que vous aurez seulement accès aux propriétés directes de anObject , et ne pas utiliser les propriétés qui sont en bas de la chaîne du prototype.

25
répondu Andreas Grech 2008-12-07 15:50:03
la source

variables privées avec Interface publique

il utilise une petite astuce soignée avec une définition de fonction d'auto-appel. Tout à l'intérieur de l'objet qui est retourné est disponible dans l'interface publique, tandis que tout le reste est privé.

var test = function () {
    //private members
    var x = 1;
    var y = function () {
        return x * 2;
    };
    //public interface
    return {
        setx : function (newx) {
            x = newx;
        },
        gety : function () {
            return y();
        }
    }
}();

assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());
23
répondu Chris MacDonald 2008-09-20 00:53:24
la source

Autres questions sur javascript hidden-features