JavaScript對象——原型與原型鏈

原型與原型鏈

一. 普通對象與函數對象
  • JavaScript 中,萬物皆對象!但對象也是有區別的。分爲普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。下面舉例說明
var o1 = {};
var o2 = new Object();
var o3 = new f1();

function f1(){};
var f2 = function(){};
var f3 = new Function('str');

typeof Object;//function
typeof Function;//function

typeof f1;//function
typeof f2;//function
typeof f3;//function

typeof o1;//object
typeof o2;//object
typeof o3;//object

在上面的例子中 o1 o2 o3 爲普通對象,f1 f2 f3 爲函數對象。怎麼區分,其實很簡單,凡是經過 new Function() 建立的對象都是函數對象,其餘的都是普通對象。f1,f2,歸根結底都是經過 new Function()的方式進行建立的。Function Object 也都是經過 New Function()建立的。函數

二.構造函數
function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        alert(this.name);
    }
}
var person1 = new Person('mike',15);
var person2 = new Person('nike',18);

上例中person1和person2爲Person的實例,兩個實例中都有隱含的
==constructor==屬性(經過原型對象繼承獲得),該屬性指向構造函數Personthis

三.原型對象
  • 咱們建立的每一個函數都有一個prototype(原型)屬性,指向函數的原型對象。換句話說,prototype就是經過調用構造函數而建立的那個對象實例的原型對象,使用原型對象便可以讓全部對象實例共享它所包含的屬性和方法,可類比於父子類(繼承)。
  • 建立新函數時,其prototype屬性指向的原型對象會自動得到一個constructor(構造函數)屬性,該屬性指向包含prototype的函數,也就是構造函數
function Person(name, age, job){
    Person.prototpe.name = father;
    Person.prototpe. = 28;
    Person.prototpe.sayName = function(){
        alert(this.name);
    }
}
var person1 = new Person();
person1.sayName();//'mike'
var person2 = new Person();
person2.sayName();//'nike'

person1.sayName == person2.sayName;//true

person1.name = 'joy';
person1.sayName();//'joy'

經過爲構造函數Person的原型對象建立屬性,person1,person2將繼承Person.prototype的屬性,若是實例定義了與原型對象同名屬性,原型對象屬性則會被覆蓋。prototype

補充:更簡單的原型語法
function Person(){}
Person.prototype = {
    name:'',
    age:'',
    sayName:function(){
    }
}

==注意==:該方法的原型對象的constructor屬性再也不指向Person,此時例中指向Object(新new的一個對象),如若須要可在Person.pertotype的字面量中添加:==constructor:Person,==設計

四.__proto__
  • JS 在建立對象(不管是普通對象仍是函數對象)的時候,都有一個叫作__proto__ 的內置屬性,用於指向建立它的構造函數的原型對象。code

  • 普通對象的__proto__指向這個對象(this)的構造函數的prototype;
  • 函數對象的__proto__所有都是指向Function的prototype。對象

對象 person1 有一個 __proto__屬性,建立它的構造函數是 Person,構造函數的原型對象是 Person.prototype ,因此:
==person1.__proto__ == Person.prototype==blog

不過,要明確的真正重要的一點就是,這個鏈接存在於實例==person1==與構造函數==Person==的原型對象==Person.prototype==之間,而不是存在於實例person1與構造函數Person之間。繼承

js高級程序設計圖
imageip

五.Prototype

當咱們建立一個函數時:
var Person = new Object()
Person 是 Object 的實例,因此 Person 繼承了Object 的原型對象Object.prototype上全部的方法:
image原型鏈

六.Object.getPrototypeOf(obj)

獲取對象的原型

總結
  • 原型和原型鏈是JS實現繼承的一種模型。
  • 原型鏈的造成是真正是靠__proto__ 而非prototype
  • 對象經過__proto__屬性訪問原型,構造函數經過prototype屬性訪問原型

  • Object 是全部對象的爸爸,全部對象均可以經過 proto 找到它
  • Function 是全部函數的爸爸,全部函數均可以經過 proto 找到它
  • Function.prototype 和 Object.prototype 是兩個特殊的對象,他們由引擎來建立
  • 除了以上兩個特殊對象,其餘對象都是經過構造器 new 出來的
  • 函數的 prototype 是一個對象,也就是原型
    對象的 proto 指向原型, proto 將對象和原型鏈接起來組成了原型鏈

相關文章
相關標籤/搜索