数据类型

数组类型

Undefined, Null, Bollean, Number, String, Object六种数组类型 Symbol (new in ECMAScript 2015)

typeof用来检测数据类型

var name;
var course = null;
var isStudent = true;
var grade = 80;
var sex = "女"
var student = {}

console.log(typeof name)
console.log(typeof course)
console.log(typeof isStudent)
console.log(typeof grade)
console.log(typeof sex)
console.log(typeof student)

// undefined
// object
// boolean
// number
// string
// object
  • 我们看到typeof null 会返回一个object 因为null会被认为是一个空对象引用。

Undefined类型

  • 只有一个undefined值
var message; //声明一个变量默认值是undefined
console.log(message) //undefined

Null类型

  • 只有一个特殊值 null,如果定义的变量用来保存对象,那么我们最好给他附上初始值null
  • 实际上undefined是派生自null值得所以他们是相等的,但不是恒等的。他们typeof的值不同
console.log(undefined == null) //true
console.log(undefined === false) //false

Boolean类型

  • 有两个值true和false
// 什么时候是false

console.log(Boolean("")) //false 空字符串
console.log(Boolean(0)) //false 0
console.log(Boolean(NaN)) //false NaN
console.log(Boolean(null)) //false null
console.log(Boolean(undefined)) //false undefined
  • 其他情况下都是true比如
console.log(Boolean([])) //true 数组
console.log(Boolean({})) //true 对象
console.log(Boolean("哈哈哈")) // true 字符串
  • if语句里会自动进行转换
var people = null;

if (!people) {
    console.log("非null")
}


// 非null

Number类型

  • 表示整数或者浮点数
console.log(070) // 八进制的56,八进制第一位必须是0然后是八进制数字(0-7)
console.log(0XA) //  十六进制的10 十六进制第一位必须是0x然后是(0-9)(A-F)
console.log(0b01) // 二进制的1 二进制是0b开头 后面是(0-1)
  • 浮点数存在误差
if (0.1 + 0.2 === 0.3) {
    console.log("0.3") //不会执行
}

NaN指非数值

console.log(3/0) //Infinity
console.log(NaN/10) //NaN
console.log(NaN === NaN) //false
  • 使用isNaN函数判断是不是数值
console.log(isNaN(NaN)) //true
  • isNaN接受到一个值后尝试把这个转换成数值如果成功就会返回false,其他就是true
console.log(isNaN('10')) //false
console.log(isNaN(true)) //false
console.log(isNaN('gg')) //true
  • 所以使用isNaN时要注意

调用isNaN函数时会先调用valueOf()方法,然后确定返回值是否可以转换成数值,如果不能则
根据这个返回值在调用toString()方法。

  • 数值转换

Number(), parseInt(), praseFloat()可以将非数值转换成数值

  • 转换规则如下
Boolean true -> 1, false -> 0
console.log(Number(true)) //1
Number 返回本身
Null null -> 0
console.log(Number(null)) //0

字符串

console.log(Number("123")) //123
console.log(Number("+123"))//123
console.log(Number("0123"))//123
console.log(Number("12.3"))//12.3
console.log(Number("0xf"))//15
console.log(Number(""))//0
console.log(Number("123哈哈哈")) //NaN
console.log(Number("哈哈123")) //NaN
console.log(Number({age: 3})) //NaN

Object

如果是对象的话会先调用对象的valueOf()方法然后在按照前面的转换规则如果转换结果是NaN,在调用toString方法然后在依照前面的规则转换成字符串

  • parseInt函数
console.log(parseInt("123")) //123
console.log(parseInt("+123"))//123
console.log(parseInt("0123"))//123
console.log(parseInt("12.3"))//12
console.log(parseInt("0xf"))//15
console.log(parseInt(""))//NaN
console.log(parseInt("123哈哈哈")) //123
console.log(parseInt("哈哈123")) //NaN

// parseInt第二个参数用来指定转换的进制
console.log(parseInt(11, 2))
//转换成二进制 3

String类型

- String 类型由0个或多个Unicode字符组成的字符串序列可由单引号或者双引号表示
- 转义字符 \n 换行 \b 空格 \\斜杠等
- 特点:一旦创建值就不能改变,要改变某个变量保存的字符串,就要先销毁原来的字符串,然后在用另一个包含新值得字符串填充该变量

对象

对象就是数据和操作的集合,“Object类型是所有它的实例的基础。换句话说,Object类型所具有的任何属性和方法也同样存在于更具体的对象中

  • 我们在Console里创建一个对象然后进行分析
var o = {};//快速创建一个对象
- __proto__的读取器(getter)暴露了一个对象的内部 [[Prototype]] 。
- 对于使用对象字面量创建的对象,这个值是 Object.prototype。
- 对于使用数组字面量创建的对象,这个值是 Array.prototype。
- 对于functions,这个值是Function.prototype。
- 对于使用 new fun 创建的对象,其中fun是由js提供的内建构造器函数之一(Array, Boolean, Date, Number, Object, String 等等),这个值总是fun.prototype。
- 对于用js定义的其他js构造器函数创建的对象,这个值就是该构造器函数的prototype属性。
    
- __proto__ 的设置器(setter)允许对象的 [[Prototype]]被变更。
- 前提是这个对象必须通过 Object.isExtensible(): 进行扩展,如果不这样,一个 TypeError 错误将被抛出。
- 要变更的值必须是一个object或null,提供其它值将不起任何作用。
- 要理解原型如何被使用,请查看相关文章:Inheritance and the prototype chain。
    
- .__proto__属性是Object.prototype 一个简单的访问器属性,其中包含了get(获取)和set(设置)的方法,任何一个__proto__的存取属性都继承于Object.
- prototype,但一个访问属性如果不是来源于Object.prototype就不拥有.__proto__属性,譬如一个元素设置了其他的.__proto__属性在Object.prototype之前,将会覆盖原有的Object.prototype。

- 上面是MDN里的描述,其实就是说__proto__指向它的原型。现在就是指向Object
  • JavaScript中几乎所有的对象都是 Object 的实例; 所有的对象都继承了Object.prototype的属性和方法,它们可以被覆盖(除了以null为原型的对象,如 Object.create(null))。
  • 例如,新的构造函数的原型覆盖原来的构造函数的原型,提供它们自己的 toString() 方法.。
  • 对象的原型的改变会传播到所有对象上,除非这些属性和方法被其他对原型链更里层的改动所覆盖。
var o = {} // o的原型链指向Object,也就说从Object继承过来的
var o = Object.create(null) //o是没有原型链的

var Person = function() {
    this.canWork = true
    this.job = ''

    this.say = function() {
        if(this.canWork) {
            console.log(this.name + ":" + "Hello" + "->" + this.job)
        }
    }
}

var Student = function(name) {
    this.job = 'Student'
    this.name = name
}

Student.prototype = new Person() //让Student的原型指向Person,那么它就拥有了Person的方法和属性

var stu = new Student("Bill")
stu.say() //Bill:Hello->Student

// Object.prototype.constructor
// 返回了一个创建该对象原型的函数引用

var o = {}
var array = new Array()
var func = new Function()

console.log(o.constructor === Object) //true
console.log(array.constructor === Array) //true
console.log(func.constructor === Function) //true
  • Object.assign(target, ...sources)
// 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象

var people = {name: "Bill"}
var son = {age: 10}

var clonePeople = Object.assign(people, {age: 3, grade: 80, son: son})
console.log(people === clonePeople)

people.age = 5
console.log(people.age) //5
console.log(clonePeople.age)//5

people.son.age = 11
console.log(people.son.age)
console.log(clonePeople.son.age)
  • 所以Object.assign这是浅拷贝(继承属性和不可枚举的属性是不能进行copy的)

  • Object.defineProperties(obj, props)

// 在一个对象上创建新的属性或者修改旧属性的值,并返回本身
// 属性本身有几种修改方式
// configurable?: boolean;
// enumerable?: boolean;
// value?: any;
// writable?: boolean;
// get?(): any;
// set?(v: any): void;

var people = {}
Object.defineProperties(people, {
    name: {
        value: "Bill",
        writable: true
    },
    age: {
        get: function() {
            return 10
        }
    }
})

people.name = "Jason"
console.log(people.name) //Jason
people.age = 11
console.log(people.age) //10
  • Object.entries() 方法返回一个给定对象自己的可枚举属性[key,value]对的数组。
var p = {name: "Bill", age: 3}
console.log(Object.entries(p)) //[["name", "Bill"], ["age", "3"]]

//将Object转换成Map
var map = new Map(Object.entries(p))

// Object.freeze() 冻结一个对象,使他不能被修改。

var p = {name: "Bill", age: 3}
var freezeP = Object.freeze(p)
console.log(Object.isFrozen(p)) //true

console.log(freezeP === p) //true
p.name = "jason"
console.log(p.name) //Bill 严格模式会报错
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容