關於javascript的原型和原型鏈,看我就夠了(一)

陌上寒發表於2018-11-02

關於js的原型和原型鏈,有人覺得這是很頭疼的一塊知識點,其實不然,它很基礎,不信,往下看 要了解原型和原型鏈,我們得先從物件說起

建立物件

建立物件的三種方式:

物件直接量

通過物件直接量建立物件,這是最簡單也是最常用的建立物件的方式

var empty = {};
var pos = {x:12,y:23};
var pos2 = {x:pos.x,y:pos.y+1};
var author={
	"my name":"陌上寒",//屬性名帶空格,必須用引號包裹
	'article-title':"關於javascript的原型和原型鏈,看我就夠了(一)",//屬性名帶連字元,必須用引號包裹
	"if":"使用保留字作為屬性名,必須用引號包裹"//使用保留字作為屬性名,必須用引號包裹
}
複製程式碼

通過new建立物件

通過new運算子建立並初始化一個新物件,關鍵字new後跟隨一個函式呼叫,這個函式成為建構函式(constructor),建構函式用來初始化一個新物件,js包含了一些內建的建構函式

var  obj = new Object()//建立一個空物件等同於 var obj = {}
var  arr = new Array()//建立一個空陣列等同於 var arr = []
...
複製程式碼

上面的Object(),Array(),都是js內建的建構函式 除了內建的建構函式,我們還可以使用自定義建構函式來初始化物件

function fun(){
	console.log("這是一個自定義建構函式")
};
var myObj= new fun();
複製程式碼

Object.create()

這個建立物件的方法似乎有些陌生,它建立一個新物件,包含兩個引數,

第一個,必需。 要用作原型的物件。 可以為 null 第二個,可選。 包含一個或多個屬性描述符的 JavaScript 物件

const obj = Object.create({x:1})//obj 繼承了屬性x

const obj2 = Object.create(Object.prototype, {
      foo: {
        writable: true,
        configurable: true,
        value: "hello"
      }
    })
    console.log(obj2);//輸出{foo: "hello"}
const obj3 = Object.create(null)//obj3不繼承任何屬性和方法
複製程式碼

建立一個空物件

//以下三種方法等效
var obj1 = {};
var obj2 = new Object()
var obj3 = Object.create(Object.prototype)
複製程式碼

今天重點說原型,明天我們再把Object.create()展開講述 簡單回顧以下,以上就是建立物件的三種方式

  • 通過物件直接量
  • 通過new建立物件
  • 通過Object.create() 馬上進入正題了,還差一點點

物件分類

我們都知道 JavaScript中萬物皆物件,但物件之間也是有區別的。分為函式物件普通物件。 函式物件可以建立普通物件,(這個我們上面講過了),回顧一下

function fun(){
	console.log("這是一個自定義建構函式")
};
var myObj= new fun();
複製程式碼

普通物件沒法建立函式物件,凡是通過new Function建立的物件都是函式物件,其他都是普通物件(通常通過Object建立),可以通過typeof來判斷。

function f1(){};
typeof f1 //"function"

var o1 = new f1();
typeof o1 //"object"

var o2 = {};
typeof o2 //"object"
複製程式碼

關於函式的建立,注意以下寫法等價

function f1(){}
等價於
var f1 = new Function();

function f21(a,b){
  alert(a+b);
}
f21(1,2)
等價於
var f22 = new Function('a','b',"alert(a+b)");
f22(1,2)
複製程式碼

簡單回顧一下 我們將物件分為函式物件普通物件,函式物件的級別要要高於普通物件,可以通過函式物件建立普通物件,但是無法通過普通物件建立函式物件 好了,進入正題!

何為js原型

每一個js物件(null除外)都和另一個物件相關聯,“另一個”物件就是原型,每一個物件都從原型繼承屬性 所有通過物件直接量建立的物件都具有同一個原型物件,可以通過Object.prototype獲取對原型物件的引用,注意以下程式碼

//dmeo1
const obj =new Object()
//等價於 const obj ={}
//等價於const obj = Object.create()
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)
複製程式碼

輸出:

關於javascript的原型和原型鏈,看我就夠了(一)

const obj = {}
console.log(obj.__proto__);
複製程式碼

輸出

關於javascript的原型和原型鏈,看我就夠了(一)

const str='陌上寒'
console.log(num.__proto__);
複製程式碼

輸出

關於javascript的原型和原型鏈,看我就夠了(一)

constructor

是建構函式建立的例項的屬性,該屬性的作用是指向建立當前物件的建構函式。(這個不是我們今天重點要介紹的)

_proto_

這是什麼?根據我們的console.log,不難發現,函式物件,普通物件,都存在__proto__,這是什麼呢?__proto__和原型鏈有什麼聯絡呢?__proto__指向誰呢?

我們明天繼續探討js原型和原型鏈,不見不散

原文連結

參考連結

簡單理解js的prototype屬性

基於js中的原型(全面講解)

JS原型與原型鏈的深入理解

三張圖搞懂JavaScript的原型物件與原型鏈

關於javascript的原型和原型鏈,看我就夠了(一)

相關文章