JS基础-变量类型和类型转换
JS 变量类型
JS中有 6 种原始值,分别是:
- boolean
- number
- string
- undefined
- symbol
- null
引用类型:
- 对象
- 数组
- 函数
JS中使用typeof能得到哪些类型?
其中一个奇怪的 null,虽然是基本变量,但是因为设计的时候null是全0,而对象是000开头,所以有这个误判。
- boolean
- number
- string
- undefined
- symbol
- object
- function
- bigint
instanceof 能正确判断对象的原理是什么?
判断一个对象与构造函数是否在一个原型链上
const Person = function() {}
const p1 = new Person()
p1 instanceof Person // true
var str = 'hello world'
str instanceof String // false
var str1 = new String('hello world')
str1 instanceof String // true
实现一个类型判断函数
- 判断null
- 判断基础类型
- 使用
Object.prototype.toString.call(target)来判断引用类型
注意: 一定是使用call来调用,不然是判断的Object.prototype的类型
之所以要先判断是否为基本类型是因为:虽然Object.prototype.toString.call()能判断出某值是:number/string/boolean,但是其实在包装的时候是把他们先转成了对象然后再判断类型的。 但是JS中包装类型和原始类型还是有差别的,因为对一个包装类型来说,typeof的值是object
/**
* 类型判断
*/
function getType(target) {
//先处理最特殊的Null
if(target === null) {
return 'null';
}
//判断是不是基础类型
const typeOfT = typeof target
if(typeOfT !== 'object') {
return typeOfT;
}
//肯定是引用类型了
const template = {
"[object Object]": "object",
"[object Array]" : "array",
// 一些包装类型
"[object String]": "object - string",
"[object Number]": "object - number",
"[object Boolean]": "object - boolean"
};
const typeStr = Object.prototype.toString.call(target);
return template[typeStr];
}
转Boolean
以下都为假值,其他所有值都转为 true,包括所有对象(空对象,空数组也转为真)。
- false
- undfined
- null
- ''
- NaN
- 0
- -0
对象转基本类型
对象在转换基本类型时,会调用valueOf, 需要转成字符类型时调用toString。
var a = {
valueOf() {
return 0;
},
toString() {
return '1';
}
}
1 + a // 1
'1'.concat(a) //"11"
也可以重写 Symbol.toPrimitive ,该方法在转基本类型时调用优先级最高。 Symbol.toPrimitive 指将被调用的指定函数值的属性转换为相对应的原始值。
类型转换
运算中其中一方为字符串,那么就会把另一方也转换为字符串
如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
1 + '1' // '11'
true + true // 2
4 + [1,2,3] // "41,2,3"
还需要注意这个表达式'a' + + 'b'
'a' + + 'b' // -> "aNaN"
因为 + 'b' 等于 NaN,所以结果为 "aNaN",你可能也会在一些代码中看到过 + '1' 的形式来快速获取 number 类型。
100 + 问题
'100' + 100 // "100100"
100 + '100' // "100100"
100 + true // 101
100 + false // 100
100 + undefined //NaN
100 + null // 100
"a common string"为什么会有length属性
通过字面量的方式创建:var a = 'string';,这时它就是基本类型值;通过构造函数的方式创建:var a = new String('string');这时它是对象类型。
基本类型是没有属性和方法的,但仍然可以使用对象才有的属性方法。这时因为在对基本类型使用属性方法的时候,后台会隐式的创建这个基本类型的对象,之后再销毁这个对象
== 操作符
对于 == 来说,如果对比双方的类型不一样的话,就会进行类型转换
判断流程:
- 首先会判断两者类型是否相同。相同的话就是比大小了
- 类型不相同的话,那么就会进行类型转换
- 会先判断是否在对比 null 和 undefined,是的话就会返回 true
- 判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number
1 == '1'
↓
1 == 1
- 判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断
'1' == true
↓
'1' == 1
↓
1 == 1
- 判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断
'1' == { a: 'b' }
↓
'1' == '[object Object]'
- 两边都是对象的话,那么只要不是同一对象的不同引用,都为false
注意,只要出现NaN,就一定是false,因为就连NaN自己都不等于NaN
对于NaN,判断的方法是使用全局函数 isNaN()
=== 操作符
不转类型,直接判断类型和值是否相同。
但是 NaN === NaN 还是false
{} 等于true还是false
var a = {};
a == true // -> ?
a == false // -> ?
答案是两个都为false
因为 a.toString() -> '[object Object]' -> NaN
1 与 Number(1)有什么区别
var a = Number(1) // 1
var b = new Number(1) // Number {[[PrimitiveValue]]: 1}
typeof (a) // number
typeof (b) // object
a == b // true
- var a = 1 是一个常量,而 Number(1)是一个函数
- new Number(1)返回的是一个对象
- a==b 为 true 是因为所以在求值过程中,总是会强制转为原始数据类型而非对象,例如下面的代码:
typeof 123 // "number"
typeof new Number(123) // "object"
123 instanceof Number // false
(new Number(123)) instanceof Number // true
123 === new Number(123) // false
console.log(!!(new Boolean(false))输出什么 [易混淆]
true
布尔的包装对象 Boolean 的对象实例,对象只有在 null 与 undefined 时,才会认定为布尔的 false 值,布尔包装对象本身是个对象,对象->布尔 都是 true,所以 new Boolean(false)其实是布尔的 true,看下面这段代码:
if(new Boolean(false)){
alert('true!!');
}
只有使用了 valueOf 后才是真正的转换布尔值,与上面包装对象与原始资料转换说明的相同:
!!(new Boolean(false)) //true
(new Boolean(false)).valueOf() //false
如何判断一个数据是不是Array
Array.isArray(obj)- ECMAScript 5种的函数,当使用ie8的时候就会出现问题。
obj instanceof Array- 当用来检测在不同的window或iframe里构造的数组时会失败。这是因为每一个iframe都有它自己的执行环境,彼此之间并不共享原型链,所以此时的判断一个对象是否为数组就会失败。此时我们有一个更好的方式去判断一个对象是否为数组。
Object.prototype.toString.call(obj) == '[object Array]'- 这个方法比较靠谱
obj.constructor === Array- constructor属性返回对创建此对象的函数的引用
Object.prototype.toString
如果是原始类型,他会将原始类型包装为引用类型,然后调用对应方法
function dd(){}
var toString = Object.prototype.toString;
toString.call(dd); //[object Function]
toString.call(new Object); //[object Object]
toString.call(new Array); //[object Array]
toString.call(new Date); //[object Date]
toString.call(new String); //[object String]
toString.call(Math); //[object Math]
toString.call(undefined); //[object Undefined]
toString.call(null); //[object Null]
toString.call(123) //[object Number]
toString.call('abc') //[object String]
obj.toString() 和Object.prototype.toString.call(obj)
同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?
这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。
输出以下代码运行结果
1 + "1"
2 * "2"
[1, 2] + [2, 1]
"a" + + "b"
- 1 + "1"
- 加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
- 所以值为:“11”
- 2 * "2"
- 乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
- Javascript中所有对象基本都是先调用valueOf方法,如果不是数值,再调用toString方法。
- 所以两个数组对象的toString方法相加,值为:"1,22,1"
- "a" + + "b"
- 后边的“+”将作为一元操作符,如果操作数是字符串,将调用Number方法将该操作数转为数值,如果操作数无法转为数值,则为NaN。
- 所以值为:"aNaN"
JS基础-变量类型和类型转换的更多相关文章
- typescript学习笔记(一)---基础变量类型
作为一个前端开发者,学习新技术跟紧大趋势是必不可少的.随着2019年TS的大火,我打算利用一个月的时间学习这门语言.接下来的几篇文章是我学习TS的学习笔记,其中也会掺杂一些学习心得.话不多说,先从基础 ...
- JS基础——变量
引用类型:对象 数组 函数 }; var b =a ; b.age = ; console.log(a.age);// 21 传递的是地址, a,b同地址 值类型: var a =100; var ...
- Go-语言基础-变量-类型-函数
第一个程序 //单行注释 /* 多行注释 */ package main // 表示当前go文件属于main包 import "fmt" // 导入包 //编译型语言需要有一个入口 ...
- PHP判断变量类型和类型转换的三种方式
前言: PHP 在变量定义中不需要(不支持)明确的类型定义.变量类型是根据使用该变量的上下文所决定的.所以,在面对页码跳转.数值计算等严格的格式需求时,就要对变量进行类型转换. 举例如下: $foo ...
- 16. js 判断变量类型,包括ES6 新类型Symbol
相信大家在开发中遇到需要判断变量类型的问题,js变量按存储类型可分为值类型和引用类型,值类型包括Undefined.String.Number.Boolean,引用类型包括object.Array.F ...
- 黑马程序员——C语言基础 变量类型 结构体
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结) (一)变量类型 1)局部变量 1> 定义:在函数内部定义的变量,称为 ...
- HTML基础--元素类型及类型转换
元素类型及类型转换 一.XHTML元素分类 根据css显示分类,XHTML元素被分为三种类型:块状元素,内联元素,可变元素 1.块状元素(block element) 1)块状元素在网页中就是以块的形 ...
- js判断变量类型,类型转换,
1.typeof 操作符 主要检测基础数据类型 var a="zhangqian"; var b=true; ; var d; var e=null; var f=new Obje ...
- console.log、toString方法与js判断变量类型
Java调用system.print.out()是会调用toString方法打印js里的console.log也是控制台打印,很多时候,我们以为也是调用toString方法,其实并不是.我们在chro ...
随机推荐
- pat 1120 Friend Numbers(20 分)
1120 Friend Numbers(20 分) Two integers are called "friend numbers" if they share the same ...
- nyoj 26-孪生素数问题(打表)
26-孪生素数问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:10 submit:43 题目描述: 写一个程序,找出给出素数范围内的所有孪生素数 ...
- RabbitMQ的入门学习
RabbitMq消息队列 参考:https://blog.csdn.net/hellozpc/article/details/81436980 什么是消息队列 MQ :message Queue ,实 ...
- SCAU-1144 数星星-HDU-1166-树状数组的应用
本文借鉴代码提供:https://www.cnblogs.com/geek1116/p/5566709.html树状数组详解:https://www.cnblogs.com/xenny/p/97396 ...
- Linux 命令记录
记录Linux下使用过的命令: Linux端 1.测试当前系统支持语言(我这用的是xshell,如果出现乱码,则在file-properties-terminal-encoding中,设置为utf-8 ...
- Java正则表达式Pattern和Matcher类
转载自--小鱼儿是坏蛋(原文链接) 概述 Pattern类的作用在于编译正则表达式后创建一个匹配模式. Matcher类使用Pattern实例提供的模式信息对正则表达式进行匹配 Pattern类 ...
- java中sleep()和wait()区别
1,sleep方法是Thread类的静态方法,wait()是Object超类的成员方法 2,sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时 ...
- SpringBoot+Vue+WebSocket 实现在线聊天
一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二 ...
- Java中我常用到的十二个最基本的快捷键
自己在Java中经常用到的快捷键先记下来方便日后学习之用: 1. Ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按 ...
- java程序员面试宝典之——Java 基础部分(1~10)
基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java"源文件中是否可以包 ...