原型:
是function物件的乙個屬性,它定義了建構函式 製造出的物件 的公共祖先。通過該建構函式產生的物件,可以繼承該原型的屬性和方法。原型也是物件
這定義有點模糊,用**解釋一下
我們在控制台中列印出了這個,首先son物件的建構函式是foo,但是我們的foo中什麼屬性都沒有,怎麼會出現乙個__proto__呢?
因為我們使用了new操作符,會隱式的建立乙個 this= 物件,這個this中有乙個__proto__屬性,這個屬性的值就是foo的原型,這個原型通俗點說,就是son的父親
假如son的父親有乙個name屬性,son就可以繼承這個name屬性,看下面**
我們foo中並沒有name這個屬性,但是foo的原型上有,我們依然列印出了 『***』
上面定義說了,原型本身就是乙個物件,現在除了name這個新新增的屬性,還有兩個屬性,constructor和__proto__
constructor屬性,這個屬性是構造器,指向構造方法本身,所以我們能使用這個foo方法
__proto__我們上面說,這個屬性是指原型,難道這son的的父親foo.prototype還有父親?對的,foo.prototype的父親是object.prototype
這上面定義了一些原始方法供我們呼叫,但是我們發現,這裡面沒有__proto__這屬性了,也就是說,object.prototype就是原型的終點了
原型鏈:
grandfoo.prototype.name = '***'; //在爺爺的原型上加乙個name屬性
function grandfoo () {}
var grandfoo = new grandfoo();
foo.prototype = grandfoo; //父親的原型變為爺爺
function foo ()
var foo = new foo()
son.prototype = foo; //兒子的原型變為父親
function son ()
var son = new son()
console.log(son.age)
console.log(son.***)
console.log(son.name)
列印結果是 18 male ***
首先列印兒子的年齡,他自己的建構函式中有age,直接列印出來
然後列印兒子的性別,他自己的建構函式中沒有,然後去找兒子的原型,兒子的原型由系統預設的改為父親了,所以到父親的建構函式上找***屬性,然後列印出來
最後列印兒子的名字,他他自己的建構函式中沒有,然後找父親的建構函式,也沒有,然後找父親的原型,也就是爺爺,還是沒有,然後找爺爺的原型,爺爺的原型是系統預設的,我們在這裡面新增了乙個name屬性,所以兒子找到了這個屬性,就列印出來了
繼承的演變:
1. 傳統形式
原理:son繼承foo,繼承foo.prototype.
缺點:不能隨便給自己原型增添屬性
過多的繼承了沒用的屬性
foo.prototype.name = 'ss'; //給foo的原型新增乙個屬性name
function foo ()
}var son = new foo() //使用new操作符建立乙個新物件,son物件的構造體就是foo
console.log(son.name);
當使用new操作符時建立的新物件中,會有乙個隱式的this物件,this物件中有乙個__proto__屬性,指向該物件的原型
我們列印son.name時,它會到自己的構造體foo()中找name屬性,但是foo()中沒有,就通過this下的__proto__找到原型,在原型上找到了name屬性,於是可以列印出name
2.
借用建構函式
原理:foo構造出自己的函式,內有許多屬性和方法。son通過改變this的指向,從而借用foo函式內的屬性、方法
缺點:
沒有實現真正的繼承,不能繼承建構函式的原型
每次建構函式都要多走乙個函式
function foo (name,age)
function son (name,age)
//call方法:第乙個引數用來改變this指向,後面的引數是形參,我們這句話是把foo的this改為son的this
//現在son就有了name和age屬性,然後執行foo這個函式,把實參傳入之後,就可以列印出值
foo.call(this,name,age)
}var son = new son('x',19); //再建立乙個物件son,傳入實參
console.log(son.name)
3. 共享原型
原理:p物件將共有原型貢獻出來以便c使用。c和p共享乙個共同的原型。
缺點:
不能隨便改動自己的原型
p.prototype =
function p () {}
c.prototype = p.prototype;
function c () {}
var c = new c()
console.log(c.name)
4. 聖杯模式
原理:在p.prototype和c之間再加入乙個中間層f,當改變c.prototype時不會改動p.prototype。解決了共享原型的缺點。
//聖杯式繼承方法
var inherit = (function() //建立乙個中間層f
return function(c,p)
}())
foo.prototype.name = 'xx'
function foo () {}
function son () {}
inherit(son,foo)
var son = new son()
console.log(son.name)
原型 原型鏈 繼承
在 js 中,一切皆物件!下面就讓我們從建立物件開始,逐步學習js中的核心知識 原型,原型鏈,繼承等 1.字面量方式建立物件 var obj var obj1 2.使用 new object 的方式建立物件 var obj2 new object obj2.name 張三 obj2.age 13 o...
原型 原型鏈和繼承
看一段 就明白了function person nick,age person.prototype.sayname function var p1 newperson byron 20 var p2 newperson casper 25 p1.sayname byron p2.sayname ca...
原型 原型鏈與繼承
面試中經常考到物件導向的一些知識,在這記錄一下,如有不對歡迎指正,願在前端的道路上共勉!一 原型 1.什麼是原型 簡單說就像css的class一樣,是公用的,給dom元素加個class名就可以公用樣式,那麼原型就相當於css裡面的class,都可以用。在建構函式建立出來的時候,系統會預設的幫建構函式...