什么是原型鏈:
每一個對象都有自己的原型,而原型也是對象,也有自己的原型,一次類推而形成的鏈式結(jié)構(gòu)就叫做原型鏈
對象訪問原型鏈中的成員采用就近原則
1.如果自己本身有就去自己的,如果自己沒有就從原型中找,如果原型中也沒有就從原型的原型中找,一次類推知道找到原型鏈的終點null,如果還沒有找到是屬性就返回undefined , 如果是方法就返回xxx is not a function.
js中的對象都是由構(gòu)造函數(shù)創(chuàng)建的
1.自定義構(gòu)造函數(shù)
function Person(name,age){
this.name = name;
this.age = age;
};
//每一個人都可以打招呼淑仆,可以添加到原型中
Person.prototype.sayHi = function(){
console.log('今天六一兒童節(jié)囤官,今晚請你洗剪吹');
};
//人類屬于哺乳動物,可以添加到原型中
Person.prototype.type = '哺乳動物';
var p1 = new Person('班長',20);
console.log(p1);
/*面試題 :請說出下面程序運行的結(jié)果
*/
console.log(p1.name);//班長 p1自己有name屬性
console.log(p1.type);//哺乳動物 p1自己雖然沒有type屬性陕见,但是它的原型有type
p1.sayHi();// p1自己雖然沒有sayHi方法泣侮,但是它的原型有
//對象取值:不存在undefined
console.log(p1.girlFriend);//undefined p1自己沒有g(shù)irlFriend即彪,原型也沒有,
//p1.eat();//程序報錯 eat is not a function p1自己沒有eat方法活尊,原型也沒有隶校,
//為什么不報錯? p1自己沒有toString p1的原型也沒有toString 但是p1的原型的原型有toString
console.log(p1.toString());
//1.查看p1的原型
console.log(p1.__proto__.constructor);//Person
console.log(p1.__proto__ === Person.prototype);//true
//2.查看p1原型的原型
console.log( p1.__proto__.__proto__.constructor);//Object
console.log( p1.__proto__.__proto__ === Object.prototype);//true
//3,查看p1的原型的原型的原型
console.log(p1.__proto__.__proto__.__proto__);//null
2.查看內(nèi)置對象的原型鏈
//1.Array對象
var arr = [10,20,30];// new Array(10,20,30)
//查看數(shù)組對象的原型鏈
console.log(arr.__proto__.constructor);//Array
console.log(arr.__proto__ === Array.prototype);//true
//查看數(shù)組對象的原型的原型
console.log(arr.__proto__.__proto__.constructor);//Object
console.log(arr.__proto__.__proto__ === Object.prototype);//true
console.log(arr.__proto__.__proto__.__proto__);//null
console.log(arr);
arr.push();//js作者將數(shù)組所有的API都放入了Array酬凳。prototype中惠况,這樣所有的數(shù)組對象都可以直接調(diào)用
arr.toString();//所有的對象原型鏈都會指向Object.prototype,這就意味著任何對象都可以調(diào)用Object原型中的方法
//2.Date對象
var date = new Date();
細節(jié):日期對象不能直接用log,會自動轉(zhuǎn)成toString字符串
console.log(date);
//查看對象內(nèi)存空間 console.dir()
console.dir(date);
//查看date的原型
console.log(date.__proto__.constructor);//Date
console.log(date.__proto__ === Date.prototype);//true
//查看date的原型的原型鏈
console.log(date.__proto__.__proto__.constructor);//Object
console.log(date.__proto__.__proto__ === Object.prototype);//true
//3.String對象(基本包裝類型 new String new Number new Boolean)
var str = new String('123');
console.log(str);
//查看str對象的原型
console.log(str.__proto__.constructor);//String
console.log(str.__proto__ === String.prototype);//true
//查看str對象原型的原型
console.log(str.__proto__.__proto__.constructor);//Object
console.log(str.__proto__.__proto__ === Object.prototype);//true
//4.DOM對象
var box = document.getElementById('box');
var p1 = document.getElementById('p1');
console.log(box);//打印HinnerHTML
console.dir(box);//打印對象內(nèi)存空間
console.dir(p1);
3.函數(shù)也是對象類型:
驗證:對象擁有點語法動態(tài)添加屬性宁仔,如果函數(shù)也能像對象一樣擁有點語法動態(tài)添加屬性
function fn(){
console.log('11111');
};
fn.sb = function(){
console.log('一群大雁飛過稠屠,一會兒拍成了s形,一會兒又拍成了b形');
};
fn.aaa = '我是函數(shù)的屬性';
fn.sb();
console.log(fn.aaa);
//log:打印函數(shù)中存儲的代碼
console.log(fn);
//dir:打印函數(shù)對象中存儲的屬性
console.dir(fn);
//2.既然函數(shù)也是對象(所有的對象都是構(gòu)造函數(shù)創(chuàng)建)翎苫,那么函數(shù)對象又是誰創(chuàng)建的呢权埠?
/* 函數(shù)是一個特殊的對象,所有的函數(shù)都是由Function構(gòu)造函數(shù)創(chuàng)建 */
console.log(fn.__proto__.constructor);//Function
console.log(fn.__proto__ === Function.prototype);//true
console.log(Object.__proto__.constructor);//Function
console.log(Array.__proto__.constructor);//Function
由上面的介紹基本上已經(jīng)可以大概了解原型鏈的雛形啦,下面就是原型鏈的完整版
06-完整的原型鏈.png
由原型對象看instanceof
<script>
/*
instanceof運算符工作原理: 對象 instanceof 構(gòu)造函數(shù)
規(guī)則: 檢查右邊構(gòu)造函數(shù)的原型煎谍,在不在左邊對象的原型鏈中
*/
//1.Array
/*根據(jù)instanceof的運算規(guī)則: 左邊Array是對象攘蔽,右邊是構(gòu)造函數(shù)
Array構(gòu)造函數(shù)對象的原型鏈:Array對象.__proto__ -> Function.prototype -> Object.prototype -> null
*/
console.log(Array instanceof Object);//true
console.log(Array instanceof Function);//true
console.log(Array instanceof Array);//false
//2.Function
/*
根據(jù)instanceof運算符規(guī)則:左邊Function是對象,右邊的Function是構(gòu)造函數(shù)
Function對象的完整原型鏈: Function -> Function.prototype - > Object.prototype -> nulll
*/
console.log(Function instanceof Function);//true
console.log(Function instanceof Object);//true
//3.Object
/*
根據(jù)instanceof運算符規(guī)則:左邊Object是對象呐粘,右邊的Object是構(gòu)造函數(shù)
Object對象的完整原型鏈: Object -> Function.prototype - > Object.prototype -> nulll
*/
console.log(Object instanceof Function);//true
console.log(Object instanceof Object);//true
</script>