Maison  >  Article  >  interface Web  >  Une compréhension plus approfondie des types primitifs en JS

Une compréhension plus approfondie des types primitifs en JS

青灯夜游
青灯夜游avant
2021-02-02 18:01:442943parcourir

Une compréhension plus approfondie des types primitifs en JS

Les types primitifs en JavaScript incluent Undefined, Null, Number, Boolean et String. D'autres variables sont des types de référence, c'est-à-dire le type d'objet. Les types primitifs sont enregistrés dans la "mémoire de pile", tandis que les types de référence sont enregistrés dans la "mémoire tas", mais généralement lors de l'utilisation de variables en JavaScript, l'emplacement de la variable en mémoire n'est pas très concerné.

L'opérateur "typeof" est utilisé pour obtenir le type de données de la valeur de la variable. typeof peut accepter des noms de variables ou des valeurs littérales comme opérandes et renvoyer une chaîne décrivant les informations sur le type de variable. Il convient de noter que la valeur de retour de typeof ne correspond pas un à un aux types en JavaScript :

  • "undefined" - la valeur de la variable n'est pas définie

  • "number" ——La valeur de la variable est une valeur numérique

  • "boolean" ——La valeur de la variable est une valeur booléenne

  • "string" ——La valeur de la variable est une chaîne

  • "object" ——La valeur de la variable est un objet ou null

  • « function » ——La valeur de la variable est Function

De plus, typeof est un opérateur comme (+, -), pas une fonction Bien que l'utilisation de "typeof(. 12)" ne provoquera pas d'erreur. Pour les opérateurs, "typeof 12" est l'utilisation appropriée.

1. indéfini et nul

La définition du type non défini dans le document ECMA-262 est :

Le type non défini a exactement une valeur, appelée indéfinie. Toute variable à laquelle aucune valeur n'a été attribuée a la valeur indéfinie. Pour les variables qui n'ont pas été déclarées à l'aide de var, son utilisation générera une erreur, mais l'utilisation de l'opérateur typeof renverra "undefined" :

var foo;
alert(foo);        // undefined
alert(bar);        // 错误
alert(typeof foo); // undefined
alert(typeof bar); // undefined
undefined est implémenté en tant que variable globale (plutôt qu'une valeur littérale comme null ), Sa valeur est "indéfinie". Dans ECMAScript 3, undefined peut se voir attribuer d'autres valeurs et a été corrigé pour être en lecture seule dans ECMAScript 5.

Le type Null n'a également qu'une seule valeur, null, qui est utilisée pour représenter une "valeur vide". La plupart des langages de programmation ont des littéraux comme null, nil, etc. utilisés pour représenter des valeurs vides. Mais contrairement à d'autres langages de programmation, JavaScript n'utilise pas null pour représenter la valeur d'une variable non initialisée (représentée par undefined).

La signification logique de null est de représenter un pointeur d'objet nul. Les objets habituels en JavaScript n'incluent pas de types de données simples, donc logiquement null signifie que la variable pointe vers un type d'objet avec une valeur nulle (pas un "{}" littéral).

Pour cette raison, vous pouvez comprendre pourquoi l'utilisation de l'opérateur typeof pour obtenir le type d'une valeur nulle entraînera "objet". La signification de la valeur nulle en JavaScript pour le type Objet est similaire à 0 pour le type Nombre et à "" pour le type Chaîne.

Undéfini et null sont tous deux utilisés pour décrire une "valeur nulle", mais dans un sens logique, undéfini est plus "de bas niveau" que nul. Dans des circonstances normales, il n'est pas nécessaire de spécifier explicitement la valeur de la variable comme étant indéfinie.

Pour une variable destinée à enregistrer un objet mais qui ne pointe pas réellement vers un objet, la valeur de la variable doit être définie sur null pour refléter le rôle de null en tant que pointeur d'objet nul et pour la distinguer de non défini. .

2. Valeur numérique

ECMAScript utilise un modèle numérique simplifié. Il n'a qu'un seul type numérique, Number, sans séparer un type entier distinct. En termes d'implémentation, le type Number adopte le format de nombres à virgule flottante double précision 64 bits défini par la norme IEEE 754.

Dans le format à virgule flottante 64 bits, 52 bits sont utilisés pour représenter la mantisse, 11 bits représentent l'exposant et 1 bit est le signe. Par conséquent, lors de la représentation d'entiers, la plage d'entiers que JavaScript peut représenter se situe entre -Math.pow(2,53) et Math.pow(2,53). Au-delà de cette plage, l'exactitude des nombres à faibles chiffres ne peut pas être garantie.

var n = Math.pow(2,53); // 9007199254740992
alert(n === n + 1);     // true, 9007199254740992 + 1得到的值还是9007199254740992

Dans le développement Web réel, si vous devez transmettre un type Long Int à Javascript pour un traitement en arrière-plan (comme Java), il est très probable qu'après que JavaScript ait analysé les données JSON dans le type Number, le résultat obtenu n'est pas celui souhaité. Important : Les derniers chiffres ont changé.

JavaScript utilise des valeurs à virgule flottante pour les opérations, il y aura donc des problèmes de précision dans la partie décimale, tout comme tous les autres langages de programmation qui utilisent le format standard IEEE 754 pour représenter les nombres à virgule flottante. Évitez les jugements d'égalité sur les parties décimales de votre code. (La partie entière est précise)

var a = 0.1;
var b = 0.2;
alert(a + b === 0.3); // false

Si la valeur dépasse la limite supérieure du nombre que JavaScript peut représenter (débordement), elle sera automatiquement convertie en une valeur Infini (ou -Infini, infini négatif) représentant infini ; si la valeur Infiniment proche de 0 et dépasse la plage de représentation JavaScript (underflow), elle sera définie sur 0 (ou -0, identique à 0). JavaScript ne provoquera pas d'erreurs de débordement (y compris lors d'une division par zéro).

var a = Number.MAX_VALUE * 2;          //Infinity
var b = Number.MIN_VALUE / 2;          //0
var c = 1 / 0;                         //Infinity or NaN, 依JS执行环境不同
var d = 0 / 0;                         // NaN

Le type Number définit une valeur spéciale NaN, qui n'est pas un nombre. La signification de NaN signifie qu'aucune valeur n'est obtenue là où une valeur devrait être obtenue. Toute opération arithmétique qui utilise NaN comme opérande donnera NaN.

另外NaN也是唯一一个使用对自身进行相等判断会得到false的数值。NaN的这个怪异之处破坏了JavaScript运算符的对称性。如果在代码中需要通过比较数值大小进行分支判断,就需要注意可能出现NaN的情况,因为使用NaN与其他数值进行大小比较总会得到false,而这可能不是你想要的结果。

var a = 10;   
a = a - "not number"         // NaN
alert(a === a);             // false
var b = 12 + a;              // NaN
var c = 10;
alert(b >= c || b < c);      // false

另一个Number类型中不常引人注目的地方是位运算。JavaScript中提供了按位操作运算符。在很多其他编程语言中,按位操作可以进行硬件级处理,所以非常快。

但是JavaScript没有整数类型,它的位操作是先把数值转换为32位整数,然后进行计算,然后再转换回去,JavaScript绝大部分运行环境是在浏览器中,与硬件相隔较远,因此位操作执行很慢。

3、字符串

与很多其他编程语言中一样,JavaScript中的字符串值也是不可变的,改变一个字符串变量的值,相当于重新生成了一个字符串并把它赋值给变量。JavaScript中的简单类型无法进行方法调用(作为this调用函数),但我们还是可以进行诸如

"abcdefg".toUpperCase();

这样的操作。这是因为JavaScript为简单数据类型提供了一种方式,把它们包装为对象类型,然后进行方法调用。”"abcdefg"“先被隐式地包装为对象,然后使用包装出的对象调用toUpperCase方法,待方法调用结束后,JavaScript再隐式地把包装对象回收。

其它简单数据类型也使用同样的方式。也可以使用JavaScript提供的构造函数显示地创建包装对象,JavaScript提供了String()、Number()和Boolean()三个构造函数,分别用于构建String、Number和Boolean类型的包装对象。

4、类型转换

ECMA-262中对数据类型的转换有详细的定义,很多JavaScript的参考资料也会列出类型转换的详细规则,这里就不再赘述了,下面只讨论一些值得注意的问题。

JavaScript有两组相等比较运算符:”===“和”!==“、”==“和”!=“。Crockford在著作《JavaScript:The Good Parts》里面列举的Bad Parts中的第一个就是”==“运算符。

原因在于”==“运算符会执行隐式的类型转换,而JavaScript中类型转换的规则又非常复杂,很容易导致代码中出现不易发现的bug。与”===“和其他编程语言中的”==“不同,JavaScript中的”==“运算符并不具备传递性: ∀x∀y∀z(x == y ∧ y == z → x == z)并不成立:

"" == "0";             // false
"" == 0;               // true
"0" == 0;              // true

Crockford和Zakas都建议不要使用“==”运算符,而使用“===”代替。若不遵循这个建议,使用“==”运算符时,请务必确保你明确知道两个比较变量的类型信息,以免发生预料之外的类型转换。

另外一个经常用到类型转换的地方是分支判断。if(和其它)语句并不要求进行分支判断的表达式结果必须为Boolean类型,而会根据特定的规则把判断表达式的结果转换为true或false后再进行判断。

if (obj !== undefined && obj !== null) {
    // code
}

// 上面的判断条件可以替换为

if (obj) {
    // code
}

上面代码中的obj代表一个对象变量,若其值为undefined或null,则被转换为false,反之转换为true。这种方式并不完全安全,若使用的变量是简单数据类型,就需要注意一些特殊值的转换规则,否则代码可能不会按照预想的方式执行。

if (typeof num === "number" && num) { 
    // if num is 0, get false
    //code
}

上面代码的本意是获取一个有效的数值类型,屏蔽了其他类型和num的值为NaN的情况(NaN会转换false)。但代码中有一个纰漏,它忽略了num值为0的情况。

0值会被转换为false,从而导致下面的代码不会被执行,这可能与编码者的本意相违背。同样使用String类型作为分支条件,也要考虑""会被自动转换为false的情况。

与分支判断中的类型转换相似的情况,是采用短路方式为变量赋值。由于JavaScript中”&&“和”||“操作符的特性,我们经常采用短路方式为变量赋值。

”&&“操作符会返回表达式中第一个可以转换为false的操作数或最后一个操作数(全为true时);”||“操作符返回表达式中第一个可以转换为true的操作数或最后一个操作数(全为false时)。

var obj = obj1 || obj2 || {}; 
var attr = obj && pro && attr;

与分支判断一样,需要警惕表达式中可能出现的特殊值:0,"",null等。

JavaScript的类型模型,提供了极大的灵活性的同时也带来了很多陷阱,编码过程中需要小心地规避这些陷阱,因为代码审查很容易忽略它们,出现问题时,它们也往往很难被发现。

更多计算机编程相关知识,请访问:编程入门!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer