JavaScript 的對象及面向對象特性

JS 的面向對象特性

一. 概念

  1. 類:有相同的特征和行為的事物的抽象
  2. 對象:類的一個實例

面向對象語言的要求:
一種面向對象語言需要向開發者提供四種基本能力:
封裝 - 把相關的信息(無論數據或方法)存儲在對象中的能力
聚集 - 把一個對象存儲在另一個對象內的能力
繼承 - 由另一個類(或多個類)得來類的屬性和方法的能力
多態 - 編寫能以多種方法運行的函數或方法的能力
————————————————W3C:ECMAScript 面向對象技術

ECMAScript 支持這些要求,因此可被是看做面向對象的。

但是 JS 中沒有類的概念,而且繼承等的方式非常復雜且無用,所以我們也說 JS 不是一個嚴格面向對象的語言。

二. 對象的判斷

對于判斷一個變量是否是對象,我們通常選擇兩個方式。

1. typeOf

typeOf 運算符有一個參數,即要檢查的變量或者值。返回值就是這個變量或者值的類型。

console.log(typeof 12); // number 數字類型
console.log(typeof 'qweqwe'); // sting 字符串類型
console.log(typeof true); // boolean 布爾類型
var fn = function() {};
console.log(typeof fn); // function 函數類型
var arr = [1, 2, 'lalala'];
console.log(typeof arr); // object 引用類型
//object 引用類型 不叫對象類型

另外還存在 undefined 類型。

2. instanceof

instanceof 方法有兩個參數:第一個是要比較的變量或者值,第二個是變量類型,返回的值是 true / false。

console.log(arr instanceof Object); // true
//表示 arr 是否為引用類型的對象
console.log(fn instanceof Object); // true
console.log(Boolean instanceof Object); // true
console.log(true instanceof Object); // false
console.log(arr instanceof Array); // true 
console.log('aa' instanceof String); // false
console.log(123 instanceof Number); // false
//直接寫的123或者"aa"這都是基本類型,除非:
var str = new String('aa');
console.log(str instanceof String); // true
var num = new Number(123);
console.log(num instanceof Number); // true

三. 如何創建一個對象

這里有兩個創建對象方式:

1. 直接創建

var 變量名={
    屬性1:值1,
    屬性2:值2,
    ... ...
    函數名: function(){
        函數內容
    }
}

舉例:

var stu = {
    name: 'Tom',
    age: 42,
    sex: 'female',
    sayHi: function() {
        console.log(this.name)
    }
  };

此時我們就創建了一個名為 stu 的對象,這個對象包括三個屬性:name, age, sex。

console.log(stu.age); // 42

同時對象可以自己調用自己內部的函數:

stu.sayHi(); // Tom

2. 對象的構造函數

在第一種直接創建方式中,我們可以想象,如果要批量創建對象,會很繁瑣。所以我們可以創建一個函數,進行對象的創建。
結構:

function 構造函數名(參數1,參數2,...){
    this.屬性1 = 參數1;
    this.屬性2 = 參數2;
    ... ...
    this.函數名= function(){
        函數內容 
    }
}

舉例:

function Student(name, age) {
    this.name = name;
    this.age = age;
    this.sayHi = function() {
        console.log("i'm " + this.name);
    };
};

此時我們就有了一個可以創建對象的函數,我們只要輸入對應的參數值,就可以得到有函數內包含的屬性的對象。
那么我們用構造函數來創建對象:

var stu1 = new Student('Tom', 42);
console.log(stu1.name); // Tom
stu1.sayHi(); // i'm Tom

構造函數創建對象有如下的優點:

  1. 創建對象,將復雜的內容簡化為一個函數
  2. 改動方便,改函數,改所有對象

四. 原型

1. 概念

每一個構造函數創建的屬性都遠原型屬性,當我們在某一個對象內創建一個原型屬性,這個屬性就被曝存在了一個獨立于每個對象空間的堵路區域,且可以被所有對象訪問到。

2. 原型的基本設置方式

Student.prototype.school = 'TsingHua';
// 此時我們就創建了一個原型屬性school,而且屬性的值都是一樣的,是TsingHua
// 這個屬性可以被所有對象訪問到
console.log(stu1.school); // TsingHua

同時原型屬性也可以是函數

Student.prototype.saySchool = function() {
    console.log('我的老家就在這個' + this.school);
    console.log(this);
};
stu1.saySchool(); 
// 我的老家就在這個TsingHua 
// Student {name: "Tom", age: 42}

3. 屬性獲取順序(原型鏈)

那么,如果此時有一個對象的 school 是其他值,那我們應該怎么辦呢?

var stuPeking = new Student('Jerry',22);
stuPeking.school='Peking University';
console.log(stuPeking.school); // Peking University
console.log(stu1.school); // TsingHua

這里就涉及到原型鏈的概念。
原型鏈是獲取屬性的先后順序:

.基本屬性 > .prototype.屬性名 > Object構造函數 > null
可以看到,基本屬性的取值優先級大于原型屬性,所以當一個對象的 school 值不是'TsingHua',那我們可以把這個對象的 school 設置為基本屬性,那么它的優先級就更高,可以設置為我們預期的值,就可以了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容