Prenez l'habitude d'écrire ensemble ! C'est le 4ème jour de ma participation au "Nuggets Daily New Plan·April Update Challenge", cliquez pour voir les détails de l'événement .
avant-propos
Je vais vous aider à trier et à apprendre en profondeur les points de connaissance des types de données JavaScript à partir des concepts de types de données, de méthodes de détection et de méthodes de conversion .
notion de type de données
Il existe 8 types de données en JavaScript, comme illustré dans la figure suivante :
Les 7 premiers types sont des types de base et le dernier type (Objet) est un type de référence, auquel vous devez également prêter attention, car il s'agit du type de données le plus fréquemment utilisé dans le travail quotidien et du type de données qui nécessite le plus d'attention aux détails techniques.
Il existe également plusieurs types de référence : Array - objet tableau, RegExp - objet normal, Date - objet date, Math - fonction mathématique, Function - objet fonction.
Différences de stockage entre les types de base et les types de référence :
- Type de base : stocké dans la mémoire de la pile, lorsqu'il est référencé ou copié, une variable complètement égale sera créée ;
- Type de référence : stockée dans la mémoire de tas, l'adresse est stockée et plusieurs références pointent vers la même adresse, ce qui implique un concept de "partage".
voir quelques cas
Sujet 1
let a = {
name: 'lee',
age: 18
}
let b = a;
console.log(a.name); // lee
b.name = 'son';
console.log(a.name); // son
console.log(b.name); // son
复制代码
Il ressort des résultats que a et b utilisent la même source de données.
sujet deux
let a = {
name: 'Julia',
age: 20
}
function change(o) {
o.age = 24;
o = {
name: 'Kath',
age: 30
}
return o;
}
let b = change(a);
console.log(b.age); // 30
console.log(a.age); // 24
复制代码
- a est passé dans change en tant que paramètre. A ce moment, a et o partagent les mêmes données, donc la modification de o affectera a.
- Lorsque o est réaffecté, il n'y a pas de connexion entre o et a.
Détection du type de données
La première méthode de jugement : typeof
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
复制代码
- Les 6 premiers sont des types de données de base ;
- Bien que typeof null affiche object , il ne s'agit que d'un bogue de longue date dans JS. Cela ne signifie pas que null est un type de données de référence et que null lui-même n'est pas un objet. Par conséquent, null renvoie un résultat discutable après typeof et ne peut pas être utilisé comme méthode pour juger null. Si vous avez besoin de juger s'il est nul dans l'instruction if, utilisez simplement '===null' pour juger.
- Si le type de données de référence est jugé par typeof, sauf que la fonction jugera comme OK , les autres sont tous des "objets", qui ne peuvent pas être jugés.
La deuxième méthode de jugement : instanceof
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
复制代码
Étant donné que toutes les données de type référence ont des prototypes, elles peuvent être jugées à partir de la chaîne de prototypes, instanceof code source :
function myInstanceof(left, right) {
// 这里先用typeof来判断基础数据类型,如果是,直接返回false
if(typeof left !== 'object' || left === null) return false;
// getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(left);
while(true) { //循环往下寻找,直到找到相同的原型对象
if(proto === null) return false;
if(proto === right.prototype) return true;//找到相同原型对象,返回true
proto = Object.getPrototypeof(proto);
}
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number)); // true
console.log(myInstanceof(123, Number)); // false
复制代码
Avantages et inconvénients des deux méthodes ci-dessus
- instanceof peut évaluer avec précision les types de données de référence complexes, mais ne peut pas évaluer correctement les types de données de base ;
- Et typeof a également des inconvénients, bien qu'il puisse juger le type de données de base (sauf null), mais le type de données de référence, en plus du type de fonction, l'autre ne peut pas être jugé.
Méthode parfaite : Object.prototype.toString
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
复制代码
Orthographe complète :
function getType(obj){
let type = typeof obj;
if (type !== "object") { // 先进行typeof判断,如果是基础数据类型,直接返回
return type;
}
// 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); // 注意正则中间有个空格
}
/* 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?思考下 */
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回
复制代码