JavaScript的原型和原型鏈 (一)
關於js的原型和原型鏈,有人覺得這是很頭疼的一塊知識點,相較於普通語法,它更難以理解一些,在開發上也較不常見。但這並不意為這它不重要,相反,它很重要。要了解原型和原型鏈,我們得先從物件說起
建立物件
通過物件字面量
通過物件直接量建立物件,這是最簡單也是最常用的建立物件的方式
let obj= {};
let LJJ = {name: "劉家軍",age: 21};
let YH = {name: "袁姮",age: LJJ.age + 1};
通過new建立物件
通過new運算子建立並初始化一個新物件,關鍵字new後跟隨一個函式呼叫,這個函式成為建構函式(constructor),建構函式用來初始化一個新物件,js包含了一些內建的建構函式
let obj = new Object()//建立一個空物件等同於 let obj = {}
let arr = new Array()//建立一個空陣列等同於 let arr = []
上面的Object(),Array(),都是js內建的建構函式
除了內建的建構函式,我們還可以使用自定義建構函式來初始化物件
function fun(){
console.log("這是一個自定義建構函式")
};
let myFun= new fun();
通過Object.create()
Object.create(proto, [propertiesObject]) 建立一個新物件,包含兩個引數
proto, 新建立物件的原型物件
propertiesObject,可選。 包含一個或多個屬性描述符的 JavaScript 物件
let obj = Object.create(Object.prototype) //建立一個空對像
const YH = {
sex: "woman",
fun() {
console.log(`我的名字是:${this.name}, 性別: ${this.sex}`);
}
};
const LJJ = Object.create(YH); // 繼承YH的 sex 屬性 與 方法
LJJ.name = "劉家軍"; // name 是LJJ上的屬性 但不是YH上的
LJJ.sex = "man"; // 繼承的屬性可以被覆蓋
LJJ.fun();
物件分類
我們都知道 JavaScript中萬物皆物件,但物件之間也是有區別的。分為函式物件和普通物件。
函式物件可以建立普通物件,(這個我們上面講過了),回顧一下
function fun(){
console.log("這是一個自定義建構函式")
};
let myFun= new fun();
普通物件沒法建立函式物件,凡是通過new Function建立的物件都是函式物件,其他都是普通物件(通常通過Object建立),可以通過typeof來判斷。
function fun1() {};
console.log(typeof fun1) // "function"
let obj1 = new fun1();
console.log(typeof obj1) // "object"
let obj2 = {};
console.log(typeof obj2) // "object"
關於函式的建立,注意以下寫法等價
function fun1() {}
等價於
let fun1 = new Function();
function fun2(a,b){
console.log(a+b);
}
fun2(1,2)
等價於
let fun2= new Function('a','b',`console.log(a+b)`);
fun2(1,2)
簡單回顧一下
我們將物件分為函式物件和普通物件,函式物件的級別要要高於普通物件,可以通過函式物件建立普通物件,但是無法通過普通物件建立函式物件
好了,進入正題!
什麼事js原型
每一個js物件(null除外)都和另一個物件相關聯,“另一個”物件就是原型,每一個物件都從原型繼承屬性
所有通過物件直接量建立的物件都具有同一個原型物件,可以通過Object.prototype獲取對原型物件的引用,注意以下程式碼
// dmeo1
const obj =new Object()
alert(obj.prototype) // undefined
alert(Object.prototype) // [object Object]
// demo2
function fun(){
console.log("這是一個自定義建構函式")
};
alert(fun.prototype) // [object Object]
看以上程式碼,obj 為普通物件,obj的prototype為undefined,Object為js內建建構函式,Object存在prototype
我們得出以下結論
每一個函式物件都有一個prototype屬性,但是普通物件是沒有的;
換個方式再說一遍,只有函式物件才會存在prototype屬性,普通的物件不存在
還沒結束,看如下程式碼
function fun(){
console.log("這是一個自定義建構函式")
};
console.log(fun.prototype)
輸出:
const obj = {}
console.log(obj.__proto__);
輸出:
const author='劉家軍'
console.log(author.__proto__);
輸出:
constructor
是建構函式建立的例項的屬性,該屬性的作用是指向建立當前物件的建構函式。(這個不是我們今天重點要介紹的)
_ _ proto_ _
這是什麼?根據我們的console.log,不難發現,函式物件,普通物件,都存在__proto__,這是什麼呢?__proto__和原型鏈有什麼聯絡呢?__proto__指向誰呢?
預知後事如何 且看明天分解