1. 程式人生 > >關於JS原型、原型鏈、繼承的問題

關於JS原型、原型鏈、繼承的問題

怎麽 都是 this -s 不是函數 一個 prototype true function

  任何對象都是被構造出來的,構造對象的方法稱為構造函數,構造函數生成的對象為構造函數的實例。聲明一個對象可以var obj = {},也可以var obj = new Object(),前者只是語法糖,等同於new Object。我們稱Object是一個構造函數,任何對象都是由Object所構造出來的

一、原型

  我們也可以自己定義構造函數並且書寫構造函數的原型(prototype)

例如:

function Person(name){
  this.name = name;
}

Person.prototype = { //註意:定義構造函數的原型,且要寫在實例化之前

  say:function() {


    console.log(this.name)
  }

}

二、繼承

如上,我們已經定義好了構造函數,書寫好了構造函數的原型,下面進行實例化:

var p1 = new Person("james"); //p1 = { name:"james"}

p1.say();  //"james"

  我們發現,p1 對象上並沒有say()方法,但卻可以調用,這是因為p1繼承了其構造函數的原型上的方法。如何繼承的呢?

  每個實例化對象上面都有一條隱式的__proto__屬性,它指向著構造函數的原型:

p1.__proto__ === Person.prototype,我們稱p1是由Person所構造出來的

當調用p1.say()方法時,p1對象沒有say這個條屬性,它會去自己的__proto__上面查找,找到後就能調用了

三、原型鏈

每個對象都有自己的原型__proto__,用於繼承構造函數prototype上面的屬性和方法,前面已經說過,prototype也是一個對象,那麽它也有自己的__proto__也可以繼承屬性和方法,一層一層,最終都會指向Object這個關系就叫原型鏈:

p1.__proto__ === Person.prototype //true

Person.prototype.__proto__ === Object.prototype //true

Object.prototype.__proto__ === null //true

另外:

  所有的函數(構造函數)也是被構造出來的,由Function所構造。

Function由頂層語言設計出來的,Object也是構造函數,所以也是由Function構造。

Object.__proto__ === Function.prototype //true

Object不是函數嗎?哪來的__proto__?納尼?你在逗我?

函數也是對象,是對象就存在__proto__,所以我只能這麽理解了。

整理一下:

Fucntion 天上來

Function.__proto__ === Function.prototype //我生了我自己

Object.__proto__ === Function.prototype //Function 生出了Object,構造Object同時就定義了Object.protoype

Function.prototype.__proto__ === Object.prototype //註意:這裏的Function.prototype是函數,這是怎麽回事呢?為了保證統一修改了指向,強行指向了Object.prototype

關於JS原型、原型鏈、繼承的問題