@轉(zhuǎn)載說(shuō)明出處犬绒。
打算寫一個(gè)專題,專門詳細(xì)的介紹node.js的方方面面盒犹,已經(jīng)用node.js兩年了懂更,算是一個(gè)總結(jié).
先說(shuō)結(jié)論:
js里對(duì)象會(huì)從原型鏈上繼承所有的方法和屬性。 會(huì)從es6類上繼承所有的私有屬性急膀。會(huì)從uitl.inherits上只繼承當(dāng)前類的私有屬性.
先上代碼吧
var A = function(){
this.name = 'aaaaaaaaaaaaaa';
}
var B = function(){
this.name = 'bbbbbbbbbbbb';
}
var C = function(){
this.name = 'cccccccccccc';
}
const util = require('util');
util.inherits(B, A);
util.inherits(C, B)
var c = new C();
console.info('------------function test----------------');
console.info(C.super_ === B);
console.info(B.super_ === A);
console.info(A.__proto__ === Function.prototype && Function.prototype === Function.__proto__ );
console.info(B.__proto__ === Function.prototype );
console.info(B.__proto__ === A.__proto__ );
console.info(Object.prototype.__proto__);
console.info(c.__proto__.__proto__.__proto__.__proto__ === Object.prototype);
下面幾句話很重要晨雳,算是對(duì)上面代碼的一個(gè)總結(jié)
1.Function.prototype是一切之母,它來(lái)產(chǎn)生函數(shù)氧吐,類。也可以說(shuō)任何類版仔,函數(shù)都是它生成的蝉揍。
這句話就代表了所有的函數(shù)的 proto 都等于 Funtion.prototype
2. js的對(duì)象產(chǎn)生是原型產(chǎn)生的熙卡,這跟其他語(yǔ)言是不一樣的滑燃,其他語(yǔ)言new C甜滨,那么就是C產(chǎn)生的艾扮,而js的對(duì)象是C的原型類型即C.prototype產(chǎn)生的。js的對(duì)象會(huì)去拿取原型鏈中的公共方法和屬性纹腌,再去類或函數(shù)中拿取私有屬性和函數(shù)
c.proto = C.prototype(C的原型);
c.proto.proto = B.prototype(B的原型);
c.proto.proto.proto = A.prototype(A的原型)击困,
c.proto.proto.proto.proto = Object.prototype(Object的原型)
c.proto.proto.proto.proto.proto = null;
**3. 類的繼承谅海,用utils.inherits繼承是 C.super_ = B; B.super_ = C; C.proto = Funciton.prototype侥袜; Function.proto = Function.prototype;
如果用es6的class繼承, 那就沒有super, C.proto = B; B.proto = C; C.proto = Function.prototype, Function.proto = Function.prototype;
總的來(lái)說(shuō),對(duì)象和類的繼承走的不是一條路線,類的繼承,爸爸是Function.prototype.人家Function有這個(gè)能力構(gòu)建函數(shù)。
對(duì)象的繼承毅哗,走的Object這條原型鏈翅睛。會(huì)把所有的原型鏈上的公共方法和屬性都帶給 對(duì)象. 對(duì)私有屬性扎酷,
用util.inherits繼承的話: 私有屬性只是當(dāng)前類的坷剧。比如對(duì)象c狞尔,只會(huì)拿去C的私有屬性研儒。
用ES6的class 繼承的話冲呢。A,B,C所有類的私有屬性都會(huì)拿過來(lái)。
var A = function(){
this.name = 'aaaaaaaaaaaaaa';
this.priA = "priA";
}
A.prototype.protoPriA = "protoPriA";
var B = function(){
this.name = 'bbbbbbbbbbbb';
this.priB = "priB";
}
var C = function(){
this.name = 'cccccccccccc';
this.priC = "priC";
}
const util = require('util');
util.inherits(B, A);
util.inherits(C, B)
var c = new C();
console.info(c.priC);
console.info(c.priB);
console.info(c.priA);
console.info(c.protoPriA);
console.info('------------function test----------------');
console.info(C.super_ === B);
console.info(B.super_ === A);
console.info(A.__proto__ === Function.prototype && Function.prototype === Function.__proto__ );
console.info(B.__proto__ === Function.prototype );
console.info(B.__proto__ === A.__proto__ );
A.prototype.sayA = function () {
console.info("i am sayA........");
}
//Function.prototype是一切之母,產(chǎn)生類,
console.info(Object.prototype.__proto__);
console.info(c.__proto__.__proto__.__proto__.__proto__ === Object.prototype);
c.sayA();
class CA {
constructor() {
this.name = 'ca';
this.priCA = 'priCA';
}
CATest(){
console.info("i am ca\n");
}
}
class CB extends CA {
constructor() {
super();
this.name = 'CB';
this.priCB = 'priCB';
}
CBTest(){
console.info("i am CB\n");
}
}
class CC extends CB {
constructor() {
super();
this.name = 'CC';
this.priCC = 'priCC';
}
CCTest(){
console.info("i am CC\n");
}
}
console.info('-----------------class test------------------');
var cc = new CC();
console.info(cc.priCA);
console.info(cc.priCB);
cc.CATest();
console.info(CC.__proto__ === CB);
console.info(CB.__proto__ === CA);
console.info(CA.__proto__ === Function.prototype && Function.prototype === Function.__proto__);
console.info(CB.__proto__ === Function.prototype); //false
console.info(CB.__proto__ === CA.__proto__); //false
//Function.prototype是一切之母进鸠,產(chǎn)生類,
console.info(Object.prototype.__proto__);
console.info(cc.__proto__.__proto__.__proto__.__proto__ === Object.prototype);