數(shù)組類型
Undefined, Null, Bollean, Number, String, Object六種數(shù)組類型 Symbol (new in ECMAScript 2015)
typeof用來(lái)檢測(cè)數(shù)據(jù)類型
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 會(huì)返回一個(gè)object 因?yàn)閚ull會(huì)被認(rèn)為是一個(gè)空對(duì)象引用。
Undefined類型
- 只有一個(gè)undefined值
var message; //聲明一個(gè)變量默認(rèn)值是undefined
console.log(message) //undefined
Null類型
- 只有一個(gè)特殊值 null,如果定義的變量用來(lái)保存對(duì)象,那么我們最好給他附上初始值null
- 實(shí)際上undefined是派生自null值得所以他們是相等的,但不是恒等的。他們typeof的值不同
console.log(undefined == null) //true
console.log(undefined === false) //false
Boolean類型
- 有兩個(gè)值true和false
// 什么時(shí)候是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 數(shù)組
console.log(Boolean({})) //true 對(duì)象
console.log(Boolean("哈哈哈")) // true 字符串
- if語(yǔ)句里會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換
var people = null;
if (!people) {
console.log("非null")
}
// 非null
Number類型
- 表示整數(shù)或者浮點(diǎn)數(shù)
console.log(070) // 八進(jìn)制的56,八進(jìn)制第一位必須是0然后是八進(jìn)制數(shù)字(0-7)
console.log(0XA) // 十六進(jìn)制的10 十六進(jìn)制第一位必須是0x然后是(0-9)(A-F)
console.log(0b01) // 二進(jìn)制的1 二進(jìn)制是0b開(kāi)頭 后面是(0-1)
- 浮點(diǎn)數(shù)存在誤差
if (0.1 + 0.2 === 0.3) {
console.log("0.3") //不會(huì)執(zhí)行
}
NaN指非數(shù)值
console.log(3/0) //Infinity
console.log(NaN/10) //NaN
console.log(NaN === NaN) //false
- 使用isNaN函數(shù)判斷是不是數(shù)值
console.log(isNaN(NaN)) //true
- isNaN接受到一個(gè)值后嘗試把這個(gè)轉(zhuǎn)換成數(shù)值如果成功就會(huì)返回false,其他就是true
console.log(isNaN('10')) //false
console.log(isNaN(true)) //false
console.log(isNaN('gg')) //true
- 所以使用isNaN時(shí)要注意
調(diào)用isNaN函數(shù)時(shí)會(huì)先調(diào)用valueOf()方法,然后確定返回值是否可以轉(zhuǎn)換成數(shù)值,如果不能則
根據(jù)這個(gè)返回值在調(diào)用toString()方法。
- 數(shù)值轉(zhuǎn)換
Number(), parseInt(), praseFloat()可以將非數(shù)值轉(zhuǎn)換成數(shù)值
- 轉(zhuǎn)換規(guī)則如下
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
如果是對(duì)象的話會(huì)先調(diào)用對(duì)象的valueOf()方法然后在按照前面的轉(zhuǎn)換規(guī)則如果轉(zhuǎn)換結(jié)果是NaN,在調(diào)用toString方法然后在依照前面的規(guī)則轉(zhuǎn)換成字符串
- parseInt函數(shù)
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第二個(gè)參數(shù)用來(lái)指定轉(zhuǎn)換的進(jìn)制
console.log(parseInt(11, 2))
//轉(zhuǎn)換成二進(jìn)制 3
String類型
- String 類型由0個(gè)或多個(gè)Unicode字符組成的字符串序列可由單引號(hào)或者雙引號(hào)表示
- 轉(zhuǎn)義字符 \n 換行 \b 空格 \\斜杠等
- 特點(diǎn):一旦創(chuàng)建值就不能改變,要改變某個(gè)變量保存的字符串,就要先銷毀原來(lái)的字符串,然后在用另一個(gè)包含新值得字符串填充該變量
對(duì)象
對(duì)象就是數(shù)據(jù)和操作的集合,“Object類型是所有它的實(shí)例的基礎(chǔ)。換句話說(shuō),Object類型所具有的任何屬性和方法也同樣存在于更具體的對(duì)象中
- 我們?cè)贑onsole里創(chuàng)建一個(gè)對(duì)象然后進(jìn)行分析
var o = {};//快速創(chuàng)建一個(gè)對(duì)象
- __proto__的讀取器(getter)暴露了一個(gè)對(duì)象的內(nèi)部 [[Prototype]] 。
- 對(duì)于使用對(duì)象字面量創(chuàng)建的對(duì)象,這個(gè)值是 Object.prototype。
- 對(duì)于使用數(shù)組字面量創(chuàng)建的對(duì)象,這個(gè)值是 Array.prototype。
- 對(duì)于functions,這個(gè)值是Function.prototype。
- 對(duì)于使用 new fun 創(chuàng)建的對(duì)象,其中fun是由js提供的內(nèi)建構(gòu)造器函數(shù)之一(Array, Boolean, Date, Number, Object, String 等等),這個(gè)值總是fun.prototype。
- 對(duì)于用js定義的其他js構(gòu)造器函數(shù)創(chuàng)建的對(duì)象,這個(gè)值就是該構(gòu)造器函數(shù)的prototype屬性。
- __proto__ 的設(shè)置器(setter)允許對(duì)象的 [[Prototype]]被變更。
- 前提是這個(gè)對(duì)象必須通過(guò) Object.isExtensible(): 進(jìn)行擴(kuò)展,如果不這樣,一個(gè) TypeError 錯(cuò)誤將被拋出。
- 要變更的值必須是一個(gè)object或null,提供其它值將不起任何作用。
- 要理解原型如何被使用,請(qǐng)查看相關(guān)文章:Inheritance and the prototype chain。
- .__proto__屬性是Object.prototype 一個(gè)簡(jiǎn)單的訪問(wèn)器屬性,其中包含了get(獲?。┖蛃et(設(shè)置)的方法,任何一個(gè)__proto__的存取屬性都繼承于Object.
- prototype,但一個(gè)訪問(wèn)屬性如果不是來(lái)源于Object.prototype就不擁有.__proto__屬性,譬如一個(gè)元素設(shè)置了其他的.__proto__屬性在Object.prototype之前,將會(huì)覆蓋原有的Object.prototype。
- 上面是MDN里的描述,其實(shí)就是說(shuō)__proto__指向它的原型。現(xiàn)在就是指向Object
- JavaScript中幾乎所有的對(duì)象都是 Object 的實(shí)例; 所有的對(duì)象都繼承了Object.prototype的屬性和方法,它們可以被覆蓋(除了以null為原型的對(duì)象,如 Object.create(null))。
- 例如,新的構(gòu)造函數(shù)的原型覆蓋原來(lái)的構(gòu)造函數(shù)的原型,提供它們自己的 toString() 方法.。
- 對(duì)象的原型的改變會(huì)傳播到所有對(duì)象上,除非這些屬性和方法被其他對(duì)原型鏈更里層的改動(dòng)所覆蓋。
var o = {} // o的原型鏈指向Object,也就說(shuō)從Object繼承過(guò)來(lái)的
var o = Object.create(null) //o是沒(méi)有原型鏈的
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
// 返回了一個(gè)創(chuàng)建該對(duì)象原型的函數(shù)引用
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)
// 方法用于將所有可枚舉的屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象
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)
所以O(shè)bject.assign這是淺拷貝(繼承屬性和不可枚舉的屬性是不能進(jìn)行copy的)
Object.defineProperties(obj, props)
// 在一個(gè)對(duì)象上創(chuàng)建新的屬性或者修改舊屬性的值,并返回本身
// 屬性本身有幾種修改方式
// 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() 方法返回一個(gè)給定對(duì)象自己的可枚舉屬性[key,value]對(duì)的數(shù)組。
var p = {name: "Bill", age: 3}
console.log(Object.entries(p)) //[["name", "Bill"], ["age", "3"]]
//將Object轉(zhuǎn)換成Map
var map = new Map(Object.entries(p))
// Object.freeze() 凍結(jié)一個(gè)對(duì)象,使他不能被修改。
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 嚴(yán)格模式會(huì)報(bào)錯(cuò)