Question

var f = function(o){ return this+":"+o+"::"+(typeof this)+":"+(typeof o) };
f.call( "2", "2" );
// "2:2::object:string"

var f = function(o){ return this+":"+(typeof this)+":"+(typeof o); };
var x = [1,/foo/,"bar",function(){},true,[],{}];
for (var i=0;i<x.length;++i) console.log(f.call(x[i],x[i]));
// "1:object:number"
// "/foo/:object:object"
// "bar:object:string"
// "function () {\n}:function:function"
// "true:object:boolean"
// ":object:object"
// "[object Object]:object:object"

Je vois les mêmes résultats dans Chrome, Firefox et Safari, donc je suppose qu'il est par la spécification , mais ... pourquoi? Et où dans la spécification est définie ce? Et pourquoi pas pour les fonctions?

Était-ce utile?

La solution

Comme défini dans la norme ECMA-262 ECMAScript Language Specification 3e édition (voir note), Il est basé sur la spécification (section 15.3.4.4):

var result = fun.call(thisArg[, arg1[, arg2[, ...]]]);  

Paramètres

thisArg

  

Détermine la valeur de cet intérieur   amusement. Si thisArg est nulle ou non définie,   ce sera l'objet global.   Dans le cas contraire, ce sera égal à   Object (thisArg) (qui est thisArg si   thisArg est déjà un objet, ou un   String, Boolean ou numéro si thisArg   est une valeur primitive de la   type correspondant). Il est donc   toujours vrai que ce typeof ==   « Objet » lorsque la fonction exécute.

Note en particulier la dernière ligne.

L'essentiel est que les primitifs js (string, number, boolean, null, undefined) sont immuables, donc une fonction ne peut pas être attaché à eux. Par conséquent, la fonction de call enveloppe la primitive dans un Object de sorte que la fonction peut être fixé.

par exemple:.

ne fonctionne pas:

var test = "string";
//the next 2 lines are invalid, as `test` is a primitive 
test.someFun = function () { alert(this); }; 
test.someFun();

Travaux:

var test = "string";
//wrap test up to give it a mutable wrapper
var temp = Object(test);
temp.someFun = function () { alert(this); };
temp.someFun();

(note) - comme patrick dw indiqué dans les commentaires, cela va changer dans ECMA-262 ECMAScript Language Specification 5ème édition en mode strict:

  

De la section 15.3.4.4:

     
    

NOTE La     thisArg valeur est transmise sans     modification comme cette valeur. Cette     est un changement de Edition 3, où     undefined ou null thisArg est remplacé     avec l'objet global et ToObject est     appliquée à toutes les autres valeurs, et que     résultat est passé comme cette valeur.

  
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top