js數據類型--object

系列文章

1 、從數據類型講原型原型鏈html

內容回顧

在JavaScript中,數據類型能夠分爲原始類型以及引用類型es6

其中原始類型包括string,number, boolean, null, undefined, symbol(ES6新增,表示獨一無二的值),這6種數據類型是按照值進行分配的,是存放在(stack)內存中的簡單數據段,能夠直接訪問,數據大小肯定,內存空間大小能夠分配。編程

引用類型包括function,object,array等能夠可使用new建立的數據,又叫對象類型,他們是存放在(heap)內存中的數據,如var a = {},變量a實際保存的是一個指針,這個指針指向對內存中的數據 {}數組

對象類型包含但不限於object、function、array、string、boolean、number、date、regexp。bash

這一篇文章則主要講object類型的功能及用法。數據結構

1、開篇

在js中,function類型的數據叫函數,又叫方法,array類型的數據叫數組,而object類型的數據就叫對象,須要根據實際狀況來區分一些文章中的對象與對象類型。函數

什麼是對象?post

對象就是封裝一個事物的屬性和功能的程序結構,是內存中保存多個屬性和方法的一塊存儲空間。動畫

什麼是面向對象編程?ui

面向對象編程(OOP)是一種編程思想,是一種對現實世界理解和抽象的方法,是計算機編程技術發展到必定階段後的產物。它的特徵是封裝、繼承、多態,優勢是易維護、易擴展、質量高、效率高。通俗的講就是以對象爲基礎來進行軟件開發的思想,舉個例子,好比咱們作一個雨滴落地的動畫,那麼能夠用面向對象的方法把雨滴當作一個對象,這個對象中包含顏色、形狀、大小、速度等屬性,同時還包括了開始下落、下落過程、落地後等方法 。

2、建立對象

一、直接量(字面量)建立

由於這種建立方法很直接,因此叫直接量,又叫字面量

var obj = {a:1}
複製代碼

二、構造函數建立

這一方法建立對象又叫工廠函數建立對象,顧名思義就是批量生產,使用這個方法咱們須要用到關鍵字new。運行環境內置了一個對象的構造函數—Object,咱們直接使用就能夠了

var  obj = new Object({a:1}); 
複製代碼

上面的例子中,咱們在Object中加了一個參數,這個參數是初始化的值(將參數賦值給新對象,不是克隆),這個參數的格式須要符合對象的格式要求,若是你傳入了一個別的類型的參數,那麼建立的就不是object類型的對象了(數據類型仍是對象,但不是object)

var a = new Object('a'); // String {"a"}
var b = new Object('{a:1}'); // String {"{a:1}"}
var c = new Object(1); // Number {1}
複製代碼

另外,若是沒有參數須要傳入,則Object後面的()能夠省略,即

var a = new Object; //{}
複製代碼

除了環境自帶的構造函數,咱們還能夠根據實際需求自定義構造函數

function Student(name,age){
	this.name = name
	this.age = age
}
var xm = new Student(‘xiaoM’,12); // Student {name: "xiaoM", age: 12}
var xh = new Student(‘xiaoH’,14); // Student {name: "xiaoH", age: 14}
複製代碼

三、Object.create建立對象

咱們知道,Object是一個構造函數,而js中函數也是對象類型的數據,因此函數也是有屬性的,而create就是其中的一個方法,該方法的做用是根據現有的對象新建立一個子對象。

var son=Object.create(父對象);
複製代碼

這句話作了2件事: 1. 建立空對象son 2. 設置son的__proto__指向父對象

上面的解釋實際上是有一點瑕疵的,由於咱們不但能夠根據現有的對象來建立子對象,還能夠根據null來建立子對象,我這麼說是想強調下null不是一個對象,雖然Object.prototype繼承自null,但null也不是一個對象,你可能會說:

typeof null === "object" // true
Object.prototype.toString(null) === "[object Object]" // true
複製代碼

但它確實不是一個對象,這是js的歷史遺留問題,詳細能夠看這裏 typeof null的前世此生

繼續回到咱們的文章上來,若是咱們使用了null做爲父對象來建立一個子對象,那麼

子對象.__proto__ === null //true
複製代碼

和Object.prototype一個級別的!!!不過不一樣的是,Object.prototype是運行環境封裝的,裏面天生有一些屬性及方法,而用null建立的子對象就像一個新生兒同樣,裏面乾乾淨淨的,什麼都沒有。

使用null建立子對象的缺點就是咱們再也不可以使用Object.prototype自帶的一些屬性及API,若是須要的話,你就得本身去實現了,好處就是這個子對象是一個乾乾淨淨的對象,裏面的一些屬性及方法能夠按照本身的想法來,不用擔憂與原型鏈上屬性重名,形成變量污染,多用於存儲數據。

四、ES6 的 class建立對象

class關鍵字是ES6引入的概念,用於定義類(對象),用法以下:

//定義類
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
複製代碼

能夠看到裏面有一個constructor方法,這就是構造方法,而this關鍵字則表明實例對象Point。

Point類除了構造方法,還定義了一個toString方法。注意,定義「類」的方法的時候,前面不須要加上function這個關鍵字,直接把函數定義放進去了就能夠了。另外,方法之間不須要逗號分隔,加了會報錯。

ES6 的類,徹底能夠看做構造函數的另外一種寫法。

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true
複製代碼

上面代碼代表,類的數據類型就是函數,類自己就指向構造函數。使用的時候,也是直接對類使用new命令,跟構造函數的用法徹底一致。

var point = new Point(2,3);
point.toString() // "(2,3)"
複製代碼

這裏執行new Point(2,3)能夠看做是執行了類Point裏的constructor方法爲x,y賦值,同時把toString函數掛到Point.prototype上去

構造函數的prototype屬性,在 ES6 的「類」上面繼續存在。事實上,類的全部方法都定義在類的prototype屬性上面。

更多class的使用說明及其餘es6的特性看一看阮一峯老師的ECMAScript 6 入門,講的很詳細,上面關於class的講解也都摘抄自阮一峯老師的這本書裏。

3、對象的遍歷

遍歷就是依次處理該數據結構的全部成員,JavaScript中的遍歷是針對表示「集合」的數據結構,主要是數組(Array)和對象(Object),ES6 又添加了Map和Set。其中對象的遍歷主要是使用for…in結構,用法以下:

var a = {a:1,b:2}
for(var k in a){
	console.log(k)
}
//a b
複製代碼

for…in 的使用中,咱們須要當心的是,他不但能夠遍歷本身的私有屬性,還會遍歷其原型鏈上的公有屬性。

私有屬性:對象自己所具備的屬性 公有屬性:包括私有屬性在內的其原型鏈上的可訪問到的屬性

var a = {a:1,b:2}
a.__proto__ = {c:4}
for(var k in a){
	console.log(k)
}
//a b c
複製代碼

咱們能夠經過obj.hasOwnProperty來判斷一個屬性是否是對象的自有屬性

for(var k in a){
	if( a.hasOwnProperty( k ) ){
        console.log(k)
	}
}
//a b
複製代碼

以上,咱們把全部能夠遍歷到的屬性叫作可枚舉屬性,那麼什麼是可枚舉屬性不可枚舉屬性呢?

可枚舉屬性是指那些內部 「可枚舉」 標誌(enumerable)設置爲 true 的屬性,對於經過直接的賦值和屬性初始化的屬性,該標識值默認爲即爲 true,對於經過 Object.definePropertyObject.create 等定義的屬性,該標識值默認爲 false。可枚舉的屬性能夠經過 for...in 循環進行遍歷(除非該屬性名是一個 Symbol)。相對的,不可枚舉屬性就是用 for...in 遍歷不到的屬性,js中內置屬性是遍歷不到的。

4、Object/Object.prototype經常使用API介紹

咱們知道不管是object、function、array仍是string、boolean、number、date,他們都是對象類型的數據,咱們在可使用console.dir()來查看一個數據的結構。這樣咱們就能夠很全面的看到一個對象上有哪些屬性了。

一、Object構造函數的方法

Object是object的構造函數,咱們使用console.dir(Object),能夠看到:

Object

Object.assign() 經過複製一個或多個對象來建立一個新的對象。

Object.create() 使用指定的原型對象和屬性建立一個新對象。

Object.defineProperty() 給對象添加一個屬性並指定該屬性的配置。

Object.defineProperties() 給對象添加多個屬性並分別指定它們的配置。

Object.entries() 返回給定對象自身可枚舉屬性的[key, value]數組。

Object.freeze() 凍結對象:其餘代碼不能刪除或更改任何屬性。

Object.getOwnPropertyDescriptor() 返回對象指定的屬性配置。

Object.getOwnPropertyNames() 返回一個數組,它包含了指定對象全部的可枚舉或不可枚舉的屬性名。

Object.getOwnPropertySymbols() 返回一個數組,它包含了指定對象自身全部的符號屬性。

Object.getPrototypeOf() 返回指定對象的原型對象。

Object.is() 比較兩個值是否相同。全部 NaN 值都相等(這與==和===不一樣)。

Object.isExtensible() 判斷對象是否可擴展。

Object.isFrozen() 判斷對象是否已經凍結。

Object.isSealed() 判斷對象是否已經密封。

Object.keys() 返回一個包含全部給定對象自身可枚舉屬性名稱的數組。

Object.preventExtensions() 防止對象的任何擴展。

Object.seal() 防止其餘代碼刪除對象的屬性。

Object.setPrototypeOf() 設置對象的原型(即內部[[Prototype]]屬性)。

Object.values() 返回給定對象自身可枚舉值的數組。

二、Object 實例和Object 原型對象的方法

Object.prototype自己是一個對象,因此咱們使用console.log(Object.prototype),就能夠看到他的結構:

Object.prototype

Object.prototype.hasOwnProperty() 返回一個布爾值 ,表示某個對象是否含有指定的屬性,並且此屬性非原型鏈繼承的。

Object.prototype.isPrototypeOf() 返回一個布爾值,表示指定的對象是否在本對象的原型鏈中。

Object.prototype.propertyIsEnumerable() 判斷指定屬性是否可枚舉

Object.prototype.toLocaleString() 直接調用 toString()方法。

Object.prototype.toString() 返回對象的字符串表示。

Object.prototype.valueOf() 返回指定對象的原始值。

因爲 Object 以及 Object.prototype 的屬性太多,這裏就不詳細闡述了,感興趣的小夥伴能夠到 MDN 觀看,強烈建議把Object、Object.prototype的屬性都過一遍。

相關文章
相關標籤/搜索