普通對象與函數(shù)對象
var o1 = {};
var o2 =new Object();
var o3 = new f1();
function f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
console.log(typeof Object); //function
console.log(typeof Function); //function
console.log(typeof f1); //function
console.log(typeof f2); //function
console.log(typeof f3); //function
console.log(typeof o1); //object
console.log(typeof o2); //object
console.log(typeof o3); //object
上面的例子中: o1柳譬、o2术辐、o3都是普通對象object贷揽,而f1、f2镜悉、f3是函數(shù)對象function
凡是通過 new Function() 創(chuàng)建的對象都是函數(shù)對象祟辟,其他的都是普通對象。f1侣肄、f2歸根結(jié)底都是通過 new Function()的方式進(jìn)行創(chuàng)建的旧困。Function Object 也都是通過 New Function()創(chuàng)建的。
構(gòu)造函數(shù)
function Student(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.intr = function() { console.log(this.name+"年齡是"+this.age) }
}
var lilei = new Student('lilei', 28, 'Software Engineer');
var hmm = new Student('hmm', 23, 'Doctor');
這個例子中l(wèi)ilei、hmm都是構(gòu)造函數(shù)Student的實(shí)例
原型對象
JavaScript中,每定義一個對象,對象中都會包含一些預(yù)定義的屬性,每個普通對象和函數(shù)對象都包含__proto__
吼具,而每個函數(shù)對象都會有prototype
屬性僚纷,指向函數(shù)的原型對象;
看一個簡單示意圖:
例子中,
Student
是構(gòu)造函數(shù)(昵稱"媽"),其prototype
(原型對象)就是Student.prototype
(昵稱"爹"),原型對象(爹)的構(gòu)造函數(shù)屬性(媽)是構(gòu)造函數(shù)拗盒,而lilei和hmm都是構(gòu)造函數(shù)Student(媽)的實(shí)例(兒子/女兒)怖竭,兒子/女兒都繼承(__proto__
)了爹,遺傳了爹的方法和屬性锣咒,用公式表示即:
Student===Student.prototype.constructor; //true
lilei.__proto__===Student.prototype; //true
- 構(gòu)造函數(shù)具有
prototype
屬性侵状,指向原型對象 - 原型對象具有
constructor
屬性赞弥,指向構(gòu)造函數(shù) - 實(shí)例對象具有
__protot__
屬性毅整,指向原型對象
從 ECMAScript 6 開始,
[[Prototype]]
可以通過Object.getPrototypeOf()
和Object.setPrototypeOf()
訪問器來訪問绽左。這個等同于 JavaScript 的非標(biāo)準(zhǔn)但許多瀏覽器實(shí)現(xiàn)的屬性__proto__
悼嫉。
原型對象其實(shí)就是普通對象,但Function.prototype除外拼窥,它是函數(shù)對象戏蔑,且沒有prototype屬性(前面說函數(shù)對象具有prototype屬性)
function Student(){};
console.log(Student.prototype) //Student{} 空對象,具有constructor屬性
console.log(typeof Student.prototype) //object
console.log(typeof Function.prototype) // function,這個特殊
console.log(typeof Object.prototype) // object
console.log(typeof Function.prototype.prototype) //undefined
原型對象的應(yīng)用
原型對象的應(yīng)用主要就是繼承
var Student = function(name){
this.name = name; // tip: 當(dāng)函數(shù)執(zhí)行時這個 this 指該構(gòu)造函數(shù)的實(shí)例
};
/*給Student添加getName方法*/
Student.prototype.getName = function(){
return this.name; // tip: 當(dāng)函數(shù)執(zhí)行時這個 this 指該構(gòu)造函數(shù)的實(shí)例
}
var lilei = new Student('lilei');
console.log(lilei.name); //'lilei' 此時 lilei 已經(jīng)有 name 這個屬性了
console.log(lilei.getName()); //lilei
原型鏈
lilei.__proto__ 是Student.prototype
Student.__proto__ 是Function.prototype
Student.prototype.__proto__ 是Object.prototype
Object.__proto__ 是Function.prototype,Object也是構(gòu)造函數(shù)
Object.prototype__proto__ 是null
本文借鑒了Yi罐可樂
: 最詳盡的 JS 原型與原型鏈終極詳解鲁纠,沒有「可能是」