Maison  >  Article  >  interface Web  >  Analyse des types de données et des variables JavaScript (avec exemples)

Analyse des types de données et des variables JavaScript (avec exemples)

不言
不言avant
2018-11-15 17:07:012067parcourir

Le contenu de cet article concerne l'analyse des types de données et des variables JavaScript (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Dans cet article, parlons des types de données et variables en JS. C’est le type de question le plus élémentaire lors de l’apprentissage de JS, mais c’est une question importante. J'espère que mon partage vous sera utile.

Au début de l'article, j'évoquerai quelques questions rencontrées lors de l'entretien :

Par exemple :

Comment comprendre le passage de paramètres par valeur ?

Qu'est-ce qu'une zone morte temporaire ?

Qu'est-ce que la promotion variable ?

Quelle est la différence entre les variables globales et les propriétés de fenêtre ? Pourquoi?

... ...

Le style de cet article est d'analyser les points de connaissances tout en insérant quelques questions d'entretien que j'ai vécues.

Types de données de base

Dans JS, il existe 6 types de données de base, à savoir les valeurs numériques, les chaînes, les valeurs booléennes, nulles, non définies et les symboles.

Pour les types de données de base, ce que nous devons comprendre, c'est que la façon dont les types de base sont stockés en mémoire est une pile. Chaque valeur est stockée séparément et ne s'affecte pas les unes les autres.

Les types de base sont accessibles par valeur. Lors de la comparaison, comparez par valeur :

1 === 1 // true

Type de données de référence

Les valeurs des types de référence sont stockées dans le tas, tandis que les références sont stockées dans la pile.

Les types de référence sont accessibles par référence. Lors de la comparaison, les références sont également comparées :

{} === {} // => false

Méthode de passage des paramètres

En JS, les paramètres peuvent être n'importe quel type de valeur, même des fonctions.

Ce qu'il faut analyser ici, c'est quel type de paramètres sont transmis ? Type de référence ou type primitif ?

Regardons d'abord un exemple de base :

var out_num = 1;

function addOne(in_num) {
    in_num += 1;
    return in_num;
}

addOne(out_num); // => 2
out_num // => 1

Dans cet exemple, nous passons un paramètre réel out_num à la fonction addOne(). À ce stade, out_num sera transmis à in_num. , c'est-à-dire qu'il existe un processus in_num = out_num interne. Le résultat final que nous voyons est que out_num n'a pas été modifié par la fonction, indiquant que in_num et out_num sont deux valeurs stockées indépendamment en mémoire, c'est-à-dire passées par valeur.

Regardons une autre transformation :

var out_obj = { value: 1 };

function addOne(in_obj) {
    in_obj.value += 1;
    return in_obj;
}

addOne(out_obj); // => { value: 2 }
out_obj // => { value: 2 }

Une question ? Les paramètres de fonction ne sont-ils pas transmis par valeur ? Pourquoi le traitement à l’intérieur de la fonction est-il reflété à l’extérieur ? C'est un super, super, super malentendu.

Tout d'abord, nous devons encore corriger notre point de vue, c'est-à-dire que les paramètres de fonction sont passés par valeur. Alors qu’est-ce que tu comprends ici ? Pour les types référence, il a été dit précédemment que les types référence sont divisés en références et en espace mémoire réel. Ici, out_obj est toujours passé à in_obj, c'est-à-dire que in_obj = out_obj, out_obj et in_obj sont deux références. Elles sont stockées en mémoire indépendamment, mais elles pointent vers la même mémoire.

et in_obj.value = 1 font l'objet même d'une exploitation directe. Les modifications apportées à l'objet réel seront synchronisées avec toutes les références qui font référence à l'objet réel.

Analyse des types de données et des variables JavaScript (avec exemples)

Analyse des types de données et des variables JavaScript (avec exemples)

Si vous regardez à nouveau cet exemple, il sera peut-être plus clair.

var out_obj = { value: 1 };

function addOne(in_obj) {
    in_obj = { value: 2 };
    return in_obj;
}

addOne(out_obj); // => { value: 2 }
out_obj // => { value: 1 }

Il vous suffit de comprendre une chose : l'affectation d'un objet entraînera le changement de l'objet réel pointé par la référence.

Comment déterminer le type de données

Il existe généralement trois méthodes spécifiques pour déterminer le type de données :

1. type d'opérateur

L'opérateur typeof renvoie une chaîne représentant le type de données. Il présente les défauts évidents suivants :

typeof null // => 'object'

typeof [] // => 'object'

Cela est dû à des bugs laissés au début de la conception du langage JS. Vous pouvez lire cet article http://2ality.com/2013/10/typ... pour en savoir plus sur la gestion de null par typeof.

Il est donc préférable d'utiliser typeof pour déterminer certains types de base, tels que les valeurs numériques, les chaînes, les valeurs booléennes, les valeurs non définies et les symboles.

2. Derrière l'opérateur instanceof

typeof est de juger le type de données en jugeant les balises de type, et instanceof est de juger le constructeur. Indique si le prototype apparaît n'importe où dans la chaîne de prototypes de l'objet.

Par exemple :

{} instanceof Object // => true

[] instanceof Array // => true
[] instanceof Object // => true

Détermine également le type personnalisé :

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
var auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// => true

console.log(auto instanceof Object);
// => true

Ainsi, pour les types de données de base sous forme de littéraux, instanceof ne peut pas être utilisé pour déterminer :

1 instanceof Number // => false

Number(1) instanceof Number // => false

new Number(1) instanceof Number // => true

3. Object.prototype.toString()

Il s'agit actuellement de la méthode la plus recommandée, qui peut déterminer n'importe quel type de données avec plus de précision et d'exactitude. , même JSON, expressions régulières, dates, erreurs, etc. Dans Lodash, la méthode Object.prototype.toString() est également au cœur de la détermination du type de données.

Object.prototype.toString.call(JSON) // => "[object JSON]"

Pour le principe derrière cela, vous pouvez lire cet article http://www.cnblogs.com/ziyunf...

Autres

Le au-dessus de trois sont des méthodes courantes pour déterminer les types de données. Des questions telles que Comment juger un tableau, comment juger NaN, comment juger des objets de type tableau et comment juger un objet vide apparaîtront également dans l'interview. Ce type de problème est relativement ouvert et la solution consiste généralement à saisir les caractéristiques essentielles des données de jugement.

Par exemple : juger des objets de type tableau.

你先要知道 JS 中类数组对象是什么样子的,并寻求一个实际的参照物,比如 arguments 就是类数组对象。那么类数组对象具有的特点是:真值 & 对象 & 具有 length 属性 & length 为整数 & length 的范围大于等于 0,小于等于最大安全正整数(Number.MAX_SAFE_INTEGER)。

在你分析特点的时候,答案就呼之欲出了。【注意全面性】

数据类型如何转换

JS 数据类型的动态性将贯穿整个 JS 的学习,这是 JS 非常重要的特性,很多现象就是因为动态性的存在而成为 JS 独有。

正是由于动态性,JS 的数据类型可能在你毫无察觉的情况下,就发生了改变,直到运行时报错。

这里主要分析下面 8 种转换规则。

1、if 语句

if 语句中的类型转换是最常见的。

if (isTrue) {
    // ...
} else {}

在 if 语句中,会自动调用 Boolean() 转型函数对变量 isTrue 进行转换。

当 isTrue 的值是 null, undefined, 0, NaN, '' 时,都会转为 false。其余值除 false 本身外都会转为 true。

2、Number() 转型函数

我们重点关注 null undefined 以及字符串在 Number() 下的转换:

Number(null) // => 0
Number(undefined) // => NaN
Number('') // => 0
Number('123') // => 123
Number('123abc') // => NaN

注意和 parseInt() 对比。

3、parseInt()

parseInt(null) // => NaN
parseInt(undefined) // => NaN
parseInt('') // => NaN
parseInt('123') // => 123
parseInt('123abc') // => 123

4、==

这里需要注意的是:

null == undefined // => true

null == 0 // => false
undefined == false // => false

null 与 undefined 的相等性是由 ECMA-262 规定的,并且 null 与 undefined 在比较相等性时不能转换为其他任何值。

5、关系操作符

对于两个字符串的比较,是比较的字符编码值:

'B'  true

一个数值,另一个其他类型,都将转为数字进行比较。

两个布尔值转为数值进行比较。

对象,先调用 valueOf(),若不存在该方法,则调用 toString()。

6、加法

加法中特别注意的是,数字和字符串相加,将数字转为字符串。

'1' + 2 => // '12'
1 + 2 => // 3

对于对象和布尔值,调用它们的 toString() 方法得到对应的字符串值,然后进行字符串相加。对于 undefined 和 null 调用 String() 取得字符串 'undeifned' 和 'null'。

{ value: 1 } + true // => "[object Object]true"

7、减法

对于字符串、布尔值、null 或者 undefined,自动调用 Number(),转换结果若为 NaN,那么最终结果为 NaN。

对于对象,先调用 valueOf(),如果得到 NaN,结果为 NaN。如果没有 valueOf(),则调用 toString()。

8、乘法、除法

对于非数值,都会调用 Number() 转型函数。

变量提升与暂时性死区

JS 中有三种声明变量的方式:var, let, const。

var 声明变量最大的一个特点是存在变量提升。

console.log(a); // undefined
var a = 1;
console.log(a); // 1

第一个打印结果表示,在声明变量 a 之前,a 就已经可以访问了,只不过并未赋值。这就是变量提升现象。(具体原因,我放在后面分析作用域的时候来写)

let 和 const 就不存在这个问题,但是又引入了暂时性死区这样的概念。

/**
* 这上面都属于变量 a 的暂时性死区
* console.log(a) // => Reference Error
*/
let a = 1;
console.log(a); // => 1

即声明 a 之前,不能够访问 a,而直接报错。

而暂时性死区的出现又引出另外一个问题,即 typeof 不再安全。你可以参考这篇文章 http://es-discourse.com/t/why...

补充:一个经典面试题

for (var i = 0; i <p>我先不再这里展开分析,我打算放到异步与事件循环机制中去分析。不过这里将 var 替换成 let 可以作为一种解决方案。如果你有兴趣,也可以先去分析。</p><p>对于 const,这里再补充一点,用于加深对基本类型和引用类型的理解。</p><pre class="brush:php;toolbar:false">const a = 1;
const b = { value: 1 };

a = 2; // => Error
b.value = 2; // => 2
b = { value: 2 }; // => Error

本质上,const 并不是保证变量的值不得改动,而是变量指向的内存地址不得改动。

声明全局变量

直接通过 var 声明全局变量,这个全局变量会作为 window 对象的一个属性。

var a = 1;
window.a // => 1

在这里提出两个问题,一是 let 声明的全局变量会成为 window 的属性吗?二是 var 声明的全局变量和直接在 window 创建属性有没有区别?

先来回答第一问题。let 声明的全局变量不会成为 window 的属性。用什么来支撑这样的结论呢?在 ES6 中,对于 let 和 const 声明的变量从一开始就形成封闭作用域。想想之前的暂时性死区。

第二个问题,var 声明的全局变量和直接在 window 创建属性存在着本质的区别。先看下面的代码:

var a = 1;
window.a // => 1

window.b = 2;

delete window.a
delete window.b

window.a // => 1
window.b // => undefined

我们可以看到,直接创建在 window 上的属性可以被 delete 删除,而 var 创建的全局属性则不会。这是现象,通过现象看本质,二者本质上的区别在于:

La valeur de l'attribut data [[configurable]] d'une variable globale déclarée à l'aide de var est fausse et ne peut pas être supprimée par delete. La valeur par défaut de [[configurable]] pour les attributs créés directement sur l'objet est true, c'est-à-dire qu'ils peuvent être supprimés par suppression. (À propos de l'attribut [[configurable]], nous le mentionnerons également lors de l'analyse des objets dans des articles ultérieurs)

Résumé

Dans cet article"Types de données et variables " Dans l'article, 7 grandes catégories sont analysées. Passons en revue :

Les types de base, les types de référence, les méthodes de transfert de paramètres, comment déterminer les types de données, comment convertir les types de données, la promotion des variables et les zones mortes temporaires, et la déclaration des variables globales.

Ce ne sont pas seulement des points de test à haute fréquence lors des entretiens de recrutement scolaire, mais aussi des points de connaissances essentiels pour l'apprentissage de JS.

Astuce 1 : Il y a une raison pour laquelle le livre "JavaScript Advanced Programming" est appelé la "Bible Front-End". C'est très nécessaire pour vous qui préparez le recrutement sur le campus ! Lisez le livre cent fois, et sa signification vous apparaîtra clairement. Vous constaterez que la plupart des points de connaissances liés à JS que vous rencontrez lors de l'entretien se trouvent dans ce livre !

Astuce2 : Dans le processus de préparation à la révision, faites attention à la modularité et à la corrélation des connaissances. Vous devez avoir la capacité de diviser vous-même les modules de connaissances, comme le module « Types de données et variables » d'aujourd'hui. La pertinence signifie que toute connaissance est liée, par exemple, elle implique des modules tels que la portée et la mémoire.

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