第一部分: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的运行性能是一种损耗

最新文章

  1. 关于数组去重的几种方法-------javascript描述
  2. java 日期转时间戳,时间戳转为日期
  3. C# 抽象类abstract
  4. 操作ACCESS数据库注意事项
  5. Lua语言的特别之处
  6. 【应用笔记】【AN001】VC#开发环境下基于以太网的4-20mA电流采集(基于modbus tcp 协议)
  7. Anysys Fluent安装教程
  8. Mysql忘记密码修改密码
  9. nojs iis asp.net mvc
  10. QT实现,通过URL下载文件的接口实现
  11. 用qsort排序
  12. 为智能硬件提供一站式解决方案——机智云GoKit评测
  13. Oracle 表空间迁移
  14. SQLServer之修改存储过程
  15. 从0开始的Hexo主题制作
  16. Android ListView滚动到指定的位置
  17. Python -- queue队列模块
  18. [转]svn检出的时候报 Unable to connect to a repository at URL错误
  19. 流畅的python和cookbook学习笔记(八)
  20. linux c编程:读写锁

热门文章

  1. 洛谷 P2671 求和
  2. Java NIO学习系列五:I/O模型
  3. 【Java中级】(四)多线程
  4. IT界的复仇者联盟解读
  5. 【原创】这一次,Chrome表现和IE11一样令人失望,围观群众有:Edge,Firefox
  6. python找质数对
  7. 【Unity游戏开发】不接SDK也能在游戏内拉起加QQ群操作?
  8. 林大妈的JavaScript基础知识(一):JavaScript简史
  9. JavaOOP 第二章继承
  10. centos7主机间免密登录、复制文件