2010-11-22 4 views
2

Javascript semble prendre quelques libertés quand il s'agit de ses types et objets intégrés.Quelle est la différence entre Math et Array en Javascript?

Pour obtenir les fonctions à l'intérieur du type Array que vous pouvez faire ceci:

> Array().slice 
    function slice() { 
    [native code] 
    } 

Voici donc tableau ressemble à une fonction standard qui est utilisé en tant que constructeur. Sauf que ... slice n'est pas une fonction membre de la fonction Array(), c'est une fonction membre de l'objet Array.

Une autre chose d'inhabituel Array() est-il semble renvoyer un objet Array si vous l'appelez avec de nouveaux() ou non:

> var a = Array() 
undefined 
> a 
[] 
> a.length 
0 

> var b = new Array() 
undefined 
> b 
[] 
> b.length 
0 

Math d'autre part semble être un construit en objet singleton c'est toujours présent (ie: pas besoin d'instancier). Vous utiliserez donc Math.min.apply avec Array en utilisant Array(). Slice.apply.

Ma question est ce qui rend Array() si différent d'un constructeur que vous écrivez vous-même et les autres objets intégrés de Javascript.

Répondre

3

Vous écrivez

Array().slice() 

Cela signifie:

  1. Appelez la fonction "Array"
  2. Rechercher une propriété appelée "tranche" sur la valeur de retour
  3. Traiter la valeur de cette propriété comme une référence à une fonction, et l'appeler

La fonction "tranche" est définie sur l'objet Array prototype, ce qui signifie que chaque instance de Array y a accès via ce nom de propriété. La clé ici est que la fonction "Array" comme vous l'appelez est référencée par le symbole "Array". Lorsque vous écrivez "Array()", cela signifie appel la fonction, et donc cette expression fait référence à un tableau instance. Il n'y a pas vraiment de différence entre un constructeur et une fonction régulière; En fait, c'est le mot-clé new qui fait la différence en modifiant la façon dont la fonction est invoquée (c'est-à-dire avec une instance Object fraîchement créée en tant que valeur de contexte this). Une fonction est libre de vérifier si this fait référence à l'objet global et, dans l'affirmative, de renvoyer un objet nouvellement créé de sa propre initiative.

L'objet "Math" est juste un objet; vous pouvez penser comme étant défini comme ceci:

var Math = { 
    min: function(n1, n2) { ... }, 
    max: function(n1, n2) { ... }, 
    // ... 
}; 
+0

Math est, au moins dans Chrome, une instance. Sur Firefox, il s'intègre directement au code natif, il n'est même pas utilisable dans une boucle 'for in'. –

+0

Oui, je suis sûr que ce n'est pas vraiment défini ainsi - ce que je voulais dire c'est que c'est juste une illustration de la nature de l'objet. – Pointy

+0

@Ivo, vous ne pouvez pas énumérer les propriétés de l'objet 'Math' avec une boucle' for-in' car elles sont décrites comme ** non-énumérables **, par exemple: 'Math.propertyIsEnumerable ('max'); 'produit' false' – CMS

6

Je vais faire quelques commentaires en ligne, en indiquant votre question:

Sauf que ... tranche n'est pas une fonction de membre du Array (), il s'agit d'une fonction membre de l'objet Array.

Plus exactement, slice est membre de l'objet Array.prototype, en exécutant Array(), vous créez un nouvel objet de tableau, qui hérite de Array.prototype, voilà pourquoi slice est disponible.

Une autre chose d'inhabituel Array() est-il semble renvoyer un objet Array si vous l'appelez avec de nouveaux() ou non:

Ce comportement est également partagé par d'autres haut-constructeurs, par exemple Function:

var fn = Function('return "foo";'); 

est équivalent à:

var fn = new Function('return "foo";'); 

Les cas sont décrits dans la spécification (The Array constructor called as a function vs new Array), bien que d'autres constructeurs présentent un comportement différent lorsque vous les utilisez avec ou sans new, par exemple, les emballages primitifs:

new Number("20");  // produces a Number object 
typeof new Number("20"); // "object" 

Number("20");   // makes type conversion 
typeof Number("20");  // "number" 

Math sur la D'autre part, semble être un objet singleton intégré qui est toujours présent (c'est-à-dire: pas besoin d'instancier). Vous utiliserez donc Math.min.apply avec Array en utilisant Array(). Slice.apply.

Oui, Math est un objet simple, pas une fonction comme Array.

Il hérite de Object.prototype et IIRC la seule différence particulière qu'il a avec un simple objet défini par l'utilisateur est qu'il est interne [[Class]] propriété contient « Math », par exemple:

Object.prototype.toString.call(Math); // "[object Math]" 

Ma question est ce que rend Array() si différent d'un constructeur que vous écrivez vous-même et les autres objets intégrés de Javascript.

Array est pas différent, vous pouvez écrire un constructeur qui se comporte de la même manière si vous invoquez new ou non, par exemple:

function Foo (arg) { 
    if (!(this instanceof Foo)) { return new Foo(arg); } 
    this.foo = arg; 
} 

new Foo('bar'); // { foo: 'bar' } 
Foo('bar');  // { foo: 'bar' } 
Questions connexes