Javascript中的基本数据类型,如何判断数据类型,作用域链的理解
第一部分:Javascript中的数据类型
javascript中 基本数据类型有 五种, 数字 number 字符串 string 布尔 boolean 未定义 undefined 空值 null
另外有引用数据类型三种: 对象 object 数组 array 函数 function
在ES6中,新增了三种数据类型 Set Map 和 Symbol
第二部分:如何判断一个数据的数据类型呢?
方法一:使用typeof 方法
示例表明,使用typeof 方法可以判断出 number, string, boolean, undefined, object, symbol, function这7种结果,二话不说 上代码
typeof 1 // number
typeof 'a' // string
typeof false // boolean
typeof undefined // undefined
typeof [] // object
typeof {} // object
typeof null // object
const a = function(){}
typeof a // function
typeof new Set() // object
typeof new Map() // object
typeof Symbol // function
typeof Symbol() // symbol
方法二: 利用instanceof 用来判断构造函数,注意 只有引用类型的数据才可以使用 instanceof 方法,
基本类型中的 数字 字符串 布尔值 可以利用 new 方法生成对象
比如 new Number(1) 就是一个对象了,就可以使用instanceof 方法
new Number(1) instanceof Number // true
new String('str') instanceof String // true
new Boolean(false) instanceof Boolean // true
[] instanceof Array // true
{} instanceof Object // true
console.log instanceof Function // true
console.log instanceof Function // true
new Map() instanceof Map // true
new Set() instanceof Set() // true
那么以此就可以编写一个判断数据类型的方法啦
function getType(param) {
if( arguments.length === 0 ) {
return '请传入参数'
}
if(param === null) {
return 'null'
}
const type = typeof param
if( type !== 'object') { // 基本类型数据或symbol或function
return type
} else { // 引用类型
if(param instanceof Array){
return 'array'
} else if(param instanceof Set ) {
return 'set'
} else if(param instanceof Map) {
return 'map'
} else if(param instanceof Object) {
return 'object'
}
}
}
附上测试结果:
getType(1) // number
getType('a') // string
getType(false) // boolean
getType([]) // array
getType(null) // null
getType(undefined) // undefined
getType({}) // object
getType(new Set()) // set
getType(new Map()) // map
getType(Symbol()) // symbol
getType(Symbol) // function
getType(console.log) // function
3.下面来讲讲 数据类型及其对应的构造函数
在Javascript的数据类型中,除了 null ,undefined其他都有自己的构造函数
比如 数字的构造函数 Number, 字符串构造函数 String, 布尔 Boolean , 对象 Object, 函数 Function , Set() Set, Map() Map
在基本类型中 可以使用 Number(1) === 1 , String('a') === 'a', Boolean(false) === false
而 new Number(1) 会得到一个对象,这个对象只有一个属性__proto__ 这个属性指向构造函数 Number
const num = new Number(1) typeof num // 'object' typeof Number(1) // number num.__proto__ === Number.prototype // Number.ptototype 下有多个方法 valueOf, toString,toFixed等,实际上对数字调用这些方法其实是调用Number.prototype上的方法 num.toString() // Number(1) === 1 Number(1) === new Number(1) // false Number(1) == new Number(1) // true 1.toSting() // 该方法会报错,因为JS无法分别.是小数点还是操作符 正确做法是 const a = 1, a.toString() 或者1['toString']() 或者(1).toString()
字符串和 布尔中道理也是一样的
const bol = new Boolean(false)
console.loog(bol) // Boolean{false}
typeof bol // 'object'
typeof Boolean(false) // 'boolean'
Boolean(false) === false // true
Boolean(false) === new Boolean(false) // false
Boolean(false) == new Boolean(false) // true
bol上同样有一个__proto__属性,指向Boolean.prototype,上面有valueOf, toString,constructor三个属性
字符串当中
const str = new String('str')
console.log(str) // String{0: 's', 1: 't', 2: 'r'}
String('str') === 'str' // true
String('str') === str // false
String('str') == str // true
str[0] === String('str')[0]
str实际上是一个对象,该对象中有三个属性,还有长度属性,
str.__proto__ === String.prototype
String('str').__proto__ === String.prototype
第三部分:接下来再谈原型和原型链,就简单地多啦
在 Javascript中,除了null,和 undefined这两个特殊的值,其他的一切都可以看做是实例对象,只是数字,字符串,布尔,symbol这样的一般不称他们为对象,
除了null, undefined以外,所有的值都有自己的隐式原型属性__proto__,该属性指向这个值得构造函数的prototype
看代码
const num = 1
const str = 'a'
const bol = false
const obj = {}
const arr = []
const sym = new Symbol()
const set = new Set()
const map = new Map()
const fun = function() {}
num.__proto__ === Number.prototype // true
str.__proto__ === String.prototype // true
bol.__proto__ == Boolean.prototype // true
obj.__proto__ == Object.prototype // true
arr.__proto__ === Array.prototype // true
sym.__proto__ === Symbol.prototype // true
map.__proto__ === Map.prototype // true
set.__proto__ === Set.prototype // true
fun.__proto__ === Function.prototype // true
也就是说,任意一个数字,字符串,布尔,数组,对象,函数,set, map, symbol,都有一个__proto__属性,指向他们各自对应的构造函数
那么 构造函数的__proto__属性会指向哪里呢?
Number.__proto__ === Function.prototype Boolean.__proto__ === Function.prototype String.__proto__ === Function.prototype Array.__proto__ === Function.prototype Map.__proto__ === Function.prototype Set.__proto__ === Function.prototype Symbol.__proto__ === Function.prototype // 也就是说所有构造函数的原型,最终指向Function的显式原型对象 那么Function.__proto__ 会指向谁呢,
因为Function本事也属于构造函数,他的隐式原型,当然指向自身的显示原型对象 Function.__proto__ === Function.prototype
最后来讲一个特殊的,对象的__proto__属性,
普通实例对象的__proto__属性,指向他的构造函数的prototype
const obj = {}
实际上相当于
const obj = new Object()
那么
obj.__proto__ === Object.prototype
最终问题来了,构造函数的显式原型对象,本身也是一个对象,他的__proto__会指向哪里呢?
结果是
除了Object构造函数以外,任意构造函数的显式原型属性的__proto__,都指向Object.prototype
也就是说
Array.prototype.__proto__ === Object.prototype
Number.prototype.__proto__ === Object.prototype
所有其他数据Boolean, Set, Map, Symbol, Promise等类型同理
特殊的
Function.prototype.__proto__ === Object.prototype
而原型链的顶端:
Object.prototype.__proto__ === null
因为对象的显式原型对象也是一个对象,也该指向Object.prototype,
单位了防止死循环,就把Object.prototype.__proto__ 指向了null, 也就到达了
原型链的最顶端
作用域链的原理:
当一个非null, undefined类型的Javasrcipt数据想要获取某个属性值,或者调用某个方法时,如果没有该属性或者方法,那么就会向这个数据的__proto__属性中去查找,
如果一层还没有,就回继续向上查找,最终查到Object.prototype.__proto__ 因为原型链顶端指向了null,那么就会停止。最终会返回一个undefined
这个就是原型链的原理
function Animal() {
this.name = '猫'
}
Animal.name = '狗'
Function.prototype.name1 = '猪'
Object.prototype.name2 = '羊'
const animal = new Animal()
console.log(animal.name ,animal.name1, animal.name2) // 猫, undefined, 羊
注意事项,尽量减少在prototype上增加属性或者操作,那样会修改整个作用域链, 对于JS的运行性能是一种损耗
Javascript中的基本数据类型,如何判断数据类型,作用域链的理解的更多相关文章
- 对 JavaScript 中的5种主要的数据类型进行值复制
定义一个函数 clone(),可以对 JavaScript 中的5种主要的数据类型(包括 Number.String.Object.Array.Boolean)进行值复制 使用 typeof 判断值得 ...
- js中的数据类型和判断数据类型
js中的数据类型和判断数据类型 基本数据类型,六大基本数据类型:字符串(String).数字(Number).布尔(Boolean).对象(Object).空(Null).未定义(Undefined) ...
- 实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本 ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
- javascript篇-typeof,instanceof,constructor,toString判断数据类型的用法和区别
javascript基本数据类型有:string,number,Boolean,undefined,null 引用类型(复杂类型):object, ES6中新增了一种数据类型:Symbol 以上数据类 ...
- javascript中对变量类型的判断
本文正式地址:http://www.xiabingbao.com/javascript/2015/07/04/javascript-type 在JavaScript中,有5种基本数据类型和1种复杂数据 ...
- javascript中apply、call和bind的区别,容量理解,值得转!
a) javascript中apply.call和bind的区别:http://www.cnblogs.com/cosiray/p/4512969.html b) 深入浅出 妙用Javascrip ...
- JavaScript学习笔记——JS中的变量复制、参数传递和作用域链
今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习.今天学习笔记主要有这样几个关键字:变量.参数传递.执 ...
- JavaScript之一: 闭包、执行环境、作用域链
这是大虾的第一篇博文,大虾试图用最直白的语言去描述出所理解的东西,大虾是菜鸟,水平有限,有误的地方希望路过的朋友们务必指正,谢谢大家了. 从读书时代一路走来,大虾在学习的时候逐渐喜欢上了去追寻根源,这 ...
随机推荐
- 工作经验之石氏thinking
经常听到N多人说工作经验这个名词:也时常听到人说工作多少年就是多少年工作经验.我听着总觉得有点别扭,感觉他们把这个名词说的太简单了,而且觉得不是工作N年就一定有所谓的工作经验.我觉得归根结底还是在于工 ...
- ThreadGroup详细讲解
import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args){ // ...
- 对DatagramSocket的使用实例(java使用UDP进行数据传输)
今天刚看懂的一点点东西,记录一下,方便自己回顾 客户端: Client.java import java.io.IOException; import java.net.DatagramPacket; ...
- 算法学习笔记,几个简单的Demo
算法初学的一些心得 前言:现在工作也快一年多了,有时间下班回家会学学算法,陆陆续续也接触了一些 貌似我知道的就冒泡排序其他的都不是很了解 最近买了一本书,边学边记录吧! 一些常用的方法 暴力破解 下面 ...
- Modify column Vs change column
引言 I know, we can not rename a column using modify column syntax,but can change column syntax. My qu ...
- C#中unit
整理的百度百科的一些关于UNIT的资料 中文名UINT 外文名typedef unsigned short UIN 性 质 32位无符号整数 应 用 是unsigned int派生出来的 ...
- Java中返回值定义为int类型的 方法return 1返回的是int还是Integer&&finally中return问题
在Java中返回值定义为int类型的 方法return 1:中返回的是Integer值,在返回的时候基本类型值1被封装为Integer类型. 定义一个Test类,在异常处理try中和finally中分 ...
- ubuntu 单机配置hadoop
前言 因为是课程要求,所以在自己电脑上安装了hadoop,由于没有使用虚拟机,所以使用单机模拟hadoop的使用,可以上传文件,下载文件. 1.安装配置JDK Ubuntu18.04是自带Java1. ...
- [P2216] [HAOI2007]理想的正方形 「单调队列」
思路:用单调队列分别维护行与列. 具体实现方法:是先用单调队列对每一行的值维护,并将a[][]每个区间的最大值,最小值分别存在X[][]和x[][]中. 那么X[][]与x[][]所存储的分别是1×n ...
- css常用知识与用法
1 类选择器就是再 某一个标签后面加上class =“” 然后再到前面去定义这个class 一定要记住前面加. 2 id选择器和类选择器是差不多的 不过id选择器前面不加.而加# ...