【JS系列】對象詳解

前言

  • 學習面向對象時咱們常說「萬物皆對象」,固然在JavaScript中也不例外。不誇張地說:沒有理解對象,就沒法理解JavaScript。本文將向你展示對象的詳細內容,但願對你有幫助。

1. 對象的定義

1.1 「萬物皆對象」一探究竟

1.1.1 都是對象
  • 布爾類型經過new Boolean()建立時是對象函數

  • 數字類型經過new Number()建立時是對象post

  • 字符串類型經過new String()建立時是對象學習

  • Date、Math、Array、RegExp自己就是對象ui

  • 函數用typeof檢測返回的是「function」,但其有屬性和方法,也像是對象(函數經過new Function()建立時是對象)this

  • Object是對象的對象spa

1.1.2 也有例外
  • 原始數據類型有 number、boolean、string、null、undefinedprototype

  • 其中null也是對象類型code

typeof true        //boolean
typeof 123         //number 
typeof "str"       //string
typeof undefined   //undefined
typeof null        //object
複製代碼
1.1.3 結論:
  • 原始數據類型的number、boolean、string、undefined不是對象類型對象

  • function關鍵字建立的函數不是對象類型繼承

  • 其他都是對象類型

1.2 到底什麼是對象?

  • 首先看看下面的對象定義
var Person = {
  name: "一燈", 
  age: 23, 
  task: function() {
    console.log('寫代碼!')
  }
}       
複製代碼
  • 是否是很像變量的定義呢?
var name = "一燈"
複製代碼
  • 實際上,對象就是一個變量,變量便是一個容器,只不過對象這個容器能夠裝各類類型的數據,而普通變量只能裝某種類型的數據。

  • 能夠把對象理解爲一個超級變量

1.3 對象的屬性和方法

  • 剛說到對象是一個容器,裏面裝的就是屬性和方法

  • 方法:即對象裏面定義的函數,如上面的task函數

  • 屬性:除了方法,其他的都是屬性,如上面的name屬性

1.4 建立對象的方式(這裏不做詳細討論)

  1. 經過字面量建立(最簡單的),即上面的那種

  2. 經過new Object()

var Person = new Object()
Person.name = "一燈"
Person.age = 23
Person.task = function() {
  console.log('寫代碼!')
}
複製代碼
  1. 經過構造函數

  2. 經過Object.create()

1.5 對象的賦值

  • 先看看普通變量的賦值
var a = 10
var b = a 
var b = 20
console.log(a) //a = 10,b的改變不會影響a
複製代碼
  • 對象賦值會怎樣呢?
var Person = {
  name: "一燈", 
  age: 23, 
}

var a = Person
a.age = 24
console.log(Person.age) //Person.age = 24,受到了a的影響
複製代碼
  • 結論:對象的「賦值」不是賦值,而賦的是地址,兩個對象指向了同一個地址,所以會相互影響。

2. 屬性

2.1 屬性的訪問方式

  1. objectName.property
  2. objectName["property"] (注意加引號)
  3. objectName[表達式] (表達式的結果必須是一個屬性名,本質和第2種是同樣的)
//1
Person.age

//2
objectName["age"]

//3
var a = "age"
objectName[a]
複製代碼

2.2 for...in遍歷屬性

var Person = {
  name: "一燈", 
  age: 23,
  tel: 123456
}

var str = ''
for (x in Person) {
  str += Person[x]+" ";
}

console.log(str) //一燈 23 123456 
複製代碼

2.3 添加屬性

  • 能夠給一個已定義的對象添加屬性
var Person = {
  name: "一燈", 
  age: 23
}

Person.tel = 123456
console.log(Person) //{ name: '一燈', age: 23, tel: 123456 }
複製代碼
  • 若屬性已經存在,則會修改屬性
var Person = {
  name: "一燈", 
  age: 23
}

Person.age = 24
console.log(Person) //{ name: '一燈', age: 24 }
複製代碼

2.4 刪除屬性

  • 可經過delete關鍵字刪除屬性
var Person = {
  name: "一燈", 
  age: 23
}

delete Person.age
console.log(Person)  //{ name: '一燈' }
複製代碼
  • 使用delete須要知道的幾點:
  • 屬性值和屬性自己都會被刪除,刪除後不可再使用,除非再次添加該屬性
  • delete僅用於刪除對象屬性,對其餘無效
  • 切記不要刪除對象中不存在的屬性,以避免程序崩潰
  • delete不會刪除繼承的屬性

2.5 屬性的屬性

  • 是的,你沒有看錯,對象的屬性也是有屬性的,屬性值只是其中一個屬性
  • 對象屬性還有其餘三個屬性:可枚舉、可配置、可讀寫,後面會介紹如何操做這些屬性

3. 方法

3.1 this關鍵字(注意:這裏是指對象方法中的this,關於this單獨講)

  • 指的是方法的全部者,即該方法隸屬的對象(下面例子中this隸屬於person對象)
var person = {
  name: "一燈", 
  age: 23, 
  show: function() {
    console.log("Hello" + this.name)
  }
}

person.show() //Hello一燈
複製代碼

3.2 方法的訪問

  • 方法經過 objectName.methodName() 的形式訪問,如上面的例子:person.show()

3.3 添加方法

person.info = function () {
  return this.name + "-" + this.age
}
複製代碼

4. 訪問器

  • 可經過 getter 和 setter 操做對象訪問器

4.1 getter(使用get關鍵字)

var person = {
  name: "一燈",
  age : 23,
  get getName() {
    return this.name;
  }
}

console.log(person.getName) //一燈
複製代碼

4.2 setter(使用set關鍵字)

var person = {
  name: "一燈",
  age : 23,
  set setName(name) {
    this.name = name;
  }
}
person.setName = "111"
console.log(person.name) //111
複製代碼

4.3 函數 VS 訪問器

  • 你已經發現了,這種方式彷佛和函數很像
//函數實現getter
var person = {
  name: "一燈",
  age : 23,
  getName: function() {
    return this.name;
  }
}

//getter:console.log(person.getName),語法更簡潔
console.log(person.getName()) //一燈

//函數實現setter
var person = {
  name: "一燈",
  age : 23,
  setName: function(name) {
    this.name = name;
  }
}

//setter:person.setName = "111",語法和操做屬性同樣
person.setName(111)
console.log(person.name) //111
複製代碼
  • 對比發現: 訪問器屬性語法更簡潔,而且方法和屬性的操做一致

  • 值得注意的一點:訪問器屬性對錯誤不那麼敏感

//setter
var person = {
  name: "一燈",
  age : 23,
  set setName(name) {
    this.name = name;
  }
}
person.sdetName = "111" //setName拼錯,可是沒有報錯
console.log(person.name) 

//函數
var person = {
  name: "一燈",
  age : 23,
  setName: function(name) {
    this.name = name;
  }
}

person.sdetName(111) //setName拼錯,報錯了
console.log(person.name) 

複製代碼

4.4 Object.defineProperty()

  • 添加訪問器屬性的另外一種方式,經過Object.defineProperty(),格式以下:
var person = {
  name: "一燈", 
  age: 23
}

//getter
Object.defineProperty(person, "getName", {
  get: function() {
    return this.name
  }
})

console.log(person.getName) //一燈

//setter
Object.defineProperty(person, "setName", {
  set: function(name) {
    return this.name = name
  }
})

person.setName = 111
console.log(person.name) //111
複製代碼

5. 構造函數

  • JavaScript採用構造的函數建立對象是一種常見的方法,一般採用首字母大寫的駝峯法命名對象

  • 而後經過new關鍵字建立對象實例

function Person(name, age) {
  this.name = "一燈",
  this.age = 23,
  this.show = function() {
    console.log(this.name + '-' +this.age)
  }
}

var person = new Person('一燈', 23)
person.show() //一燈-23
複製代碼

5.1 this關鍵字

  • this關鍵字隸屬於經過構造函數建立的實例,上面的例子this指向person對象

5.2 添加屬性和方法到對象

//添加屬性
person.tel = 123456

//添加方法
person.task = function() {
  console.log("寫代碼!")
}
複製代碼

5.3 添加屬性和方法到構造函數

  • 向構造函數添加屬性和方法與對象中不一樣,像這樣Person.tel = 123456 是無效的
  • 只能在構造函數中添加
function Person(name, age) {
  this.name = "一燈",
  this.age = 23,
  this.tel = 123456,         //新增的屬性
  this.show = function() {
    console.log(this.name + '-' +this.age)
  },
  this.task = function() {   //添加的方法
    console.log("寫代碼!")
  }
}
複製代碼

5.4 內置的構造函數

  • 即咱們熟悉的Object、Function、Array、Date、RegExp、String、Boolean、Number
  • 注意:Math()是一個全局對象,不能使用new
  • **特別注意:**雖然有原始數據類型(boolean、number等等)的對象版本,但儘可能避免使用new 的方式建立,使用原始值會更快。

6. 原型prototype

  • js中全部對象都從原型中繼承屬性和方法,原型是很是重用的概念

  • 上一章節說到,向構造函數中添加屬性或方法須要在構造函數中添加。還有一種方式是:經過原型

function Person(name, age) {
  this.name = "一燈",
  this.age = 23,
  this.show = function() {
    console.log(this.name + '-' +this.age)
  }
}

Person.prototype.tel = 123456
Person.prototype.task = function() {
  console.log("寫代碼!")
}

var person = new Person()
console.log(person.tel) //123456
person.task() //寫代碼!
複製代碼
  • 關於原型/原型鏈的詳細內容戳這裏

6. Object的內置方法(待完善)

6.1 Object.defineProperty(object, property, descriptor)

6.2 Object.defineProperties(object, descriptors)

6.3 Object.keys(object)

6.4 Object.freeze(object)

6.5 Object.isFrozen(object)

6.6 Object.seal(object)

6.7 Object.isSealed(object)

相關文章
相關標籤/搜索