1、資料型別、typeof運算子
JavaScript 語言的每一個值,都屬於某一種資料型別。Javascript的資料型別共有7種(ES6新增一種Symbol型別)。 基本資料型別是不能再細分了,而複雜資料型別往往是多個基本資料型別的值組合而成
- 基本資料型別:Undefined、Null、Bollean、Number、String、Symbol(ES6新增)
- 複雜資料型別(引用型別):Object
typeof 操作符:typeof操作符可以檢測給定變數的資料型別,返回下列某個字串
- “undefined“--- 未定義
- “bollean” --- 布林值
- “string” --- 字串
- “number” --- 數值
- “object” --- 物件或null
- “function” --- 函式
2、物件和函式的關係
我們知道引用型別是一種資料結構,用於將資料和功能組織在一起。物件是某個特定引用型別的例項。新物件是使用new操作符後跟一個建構函式來建立的。可以這麼說,物件都是通過函式建立的。
function Person(name){
this.name = name;
}
var p1 = new Person('a');
console.log(p1);
複製程式碼
3、建構函式
建構函式本身就是一個函式,與普通函式沒有任何區別,不過為了規範一般將其首字母大寫。建構函式和普通函式的區別在於,使用new 生成例項的函式就是建構函式,直接呼叫的就是普通函式。
建立例項,使用new操作符,這種方式呼叫建構函式實際上會經歷以下4個步驟:
- (1)建立一個新物件
- (2)將建構函式的作用域賦給新物件(因此this就指向了這個新物件)
- (3)執行建構函式中的程式碼(喂這個新物件新增屬性)
- (4)返回新物件
程式碼實現模擬new
function create(){
// 1、獲得建構函式,同時刪除 arguments 中第一個引數
Con = [].shift.call(arguments);
// 2、建立一個空的物件並連結到原型,obj 可以訪問建構函式原型中的屬性
var obj = Object.create(Con.prototype);
// 3、繫結 this 實現繼承,obj 可以訪問到建構函式中的屬性
var ret = Con.apply(obj, arguments);
// 4、優先返回建構函式返回的物件
return ret instanceof Object ? ret : obj;
}
複製程式碼
4、原型
我們建立的每個函式都有一個 prototype(原型)屬性,這個屬性是一個指標,指向物件。 通過這個prototype屬性可以讓所有物件例項共享它所包含的屬性和方法。 如:
function Person(){}
Person.prototype.name = 'mike';
Person.prototype.sayName = function(){
console.log(this.name);
};
var p1 = new Person();
var p2 = new Person();
複製程式碼
這裡由new建立的p1和p2例項就都擁有name屬性和sayName方法
[[Prototype]] 和__proto__
該例項p1,p2將包含一個指標 [[Prototype]]
,指向建構函式的原型物件,在指令碼中沒有標準方式訪問[[Prototype]],但是Firefox,Safari和Chrome在每個物件上都支援 __proto__
5、原型鏈
每個物件擁有一個原型物件,通過 __proto__
指標指向上一個原型 ,並從中繼承方法和屬性,同時原型物件也可能擁有原型,這樣一層一層,最終指向 null。這種關係被稱為原型鏈 (prototype chain),通過原型鏈一個物件會擁有定義在其他物件中的屬性和方法。
function Parent(age) {
this.age = age;
}
var p = new Parent(50);
p; // Parent {age: 50}
p.__proto__ === Parent.prototype; // true
p.__proto__.__proto__ === Object.prototype; // true
p.__proto__.__proto__.__proto__ === null; // true
複製程式碼
下圖展示了原型鏈的運作機制