-
Js 對象之間的繼承
構(gòu)造函數(shù)的屬性繼承
-
①對象拷貝 :使用for....in循環(huán)繼承父對象屬性
<script> var student1 = { name : "lisi", id : 1213, meaasge : function(){ console.log(name + "," + id); } }; //使用for....in循環(huán)繼承父對象屬性 //封裝成一個函數(shù) function student(parent,child){ for (var k in parent) { if (child[k]) { continue;//對于student2里獨有的要保留的值,則跳過該次循環(huán) } child[k] = parent[k]; } } student(student1,student2); console.log(student2); </script>
上述繼承父對象是對象拷貝判哥,實際上繼承指的是類型和類型之間的繼承遥倦,而封裝的構(gòu)造函數(shù)就是用來創(chuàng)建類對象的
-
②原型繼承
//原型繼承 function Person(name, age, sex, score) { this.name = name; this.age = age; this.sex = sex; } //抽象谤绳,提取所有的公共屬性,放到一個父類型中 function Student(score){ this.score = score; } function Teacher(course){ this.crouse = crouse; } //原型對象袒哥,可以將自己的屬性和方法繼承給將來的實例對象使用 Student.prototype = new Person("li",21,"male"); //生成一個實例 var s1 = new Student(90); console.dir(s1);
????原型繼承缩筛,在沒有修改constructor之前,Student是沒有自己的constructor屬性的堡称,但它有繼承Person對象是的constructor屬性瞎抛,它指向的是Person。所以却紧,這里需要人為定義一個constructor屬性桐臊,指向Student胎撤。
//原型對象,可以將自己的屬性和方法繼承給將來的實例對象使用 Student.prototype = new Person("li",21,"male"); Studnet.prototype.constructor = Student; //生成一個實例 var s1 = new Student(90); console.dir(s1); console.log(s1.constructor);
這種繼承的缺點是豪硅,只能繼承一次哩照,不適用屬性的繼承。
-
③函數(shù)的 call 方法
//函數(shù)的 call 方法 function fn(a,b){ console.log(this);//指向的是window console.log(a+b); } var name = { name:"li" }; //普通函數(shù)的調(diào)用fn(1懒浮,1) //call方法 第一個參數(shù)用來指定this飘弧,第二個及以后傳的是實參。 fn.call(name,3,3);
? ? ? ?函數(shù)call 砚著,函數(shù)本身就是一種對象捎琐,可以有自己的屬性和方法簇爆。call方法本身就是一種指向函數(shù)的方法。
? ? ? ? call方法 在調(diào)用函數(shù)的時候,有兩個功能:①更改函數(shù)內(nèi)部的this指向愉耙;②調(diào)用函數(shù)執(zhí)行內(nèi)部代碼,其當(dāng)調(diào)用時炕舵,第一個參數(shù)用來指定this拄查,第二個及以后傳的是實參。
-
④借用構(gòu)造函數(shù)繼承屬性
? ? ? ?直接對父類型的構(gòu)造函數(shù)進行一個普通調(diào)用餐胀,在調(diào)用的過程中哟楷,內(nèi)部的this指向的是window,通過call方法更改Person內(nèi)部的this指向調(diào)用函數(shù)(如否灾,student調(diào)用的卖擅,使用call方法后,this指向的是student)
//借用構(gòu)造函數(shù)繼承屬性 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } //抽象墨技,提取所以的公共屬性惩阶,放到一個父類型中 function Student(name,age,sex,score){ //對父類型進行一個普通調(diào)用 Person.call(this,name,age,sex); this.score = score; } function Teacher(name,age,sex,course){ Person.call(this,name,age,sex) this.crouse = crouse; } var s2 = new Student("li",22,"male",90); console.dir(s2);
-
構(gòu)造函數(shù)的方法的繼承
for...in繼承、原型繼承扣汪、
①for...in繼承
//構(gòu)造函數(shù)的方法繼承 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } //抽象断楷,提取所有的公共屬性,放到一個父類型中 Person.prototype.message = function(){ console.log(123); } function Student(name,age,sex,score){ Person.call(this,name,age,sex); this.score = score; } function Teacher(name,age,sex,course){ Person.call(this,name,age,sex) this.crouse = crouse; } //for ..in繼承 for(var k in Person.prototype){ //Student保留自己的constructor 不讓Studnet繼承Person的constructor if(k == "constructor"){ continue; } Student.prototype[k] = Person.prototype[k]; }
②原型繼承
//原型繼承 Student.prototype = new Person(); //在繼承的情況下也不能改變Student的constructor的指向 Student.prototype.constructor = Student; var s1 = new Student("li",21,"male",91); s1.message(); console.dir(s1);
③組合繼承:屬性在構(gòu)造函數(shù)內(nèi)部繼承私痹,方法通過原型繼承
//構(gòu)造函數(shù)的方法繼承 function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } //抽象脐嫂,提取所有的公共屬性,放到一個父類型中 Person.prototype.message = function(){ console.log(123); } function Student(name,age,sex,score){ //屬性的繼承紊遵,使用call方法繼承 Person.call(this,name,age,sex); this.score = score; } function Teacher(name,age,sex,course){ Person.call(this,name,age,sex) this.crouse = crouse; } //方法繼承账千,通過原型繼承 Student.prototype = new Person(); //在繼承的情況下也不能改變Student的constructor的指向 Student.prototype.constructor = Student; var s1 = new Student("li",21,"male",91); s1.message(); console.dir(s1);
通過實例對象本身查找自己原型鏈的方法,這個方法繼承的是Person的方法暗膜,再查找new Person()的實例對象的原型對象匀奏,查找出它的方法。
Student函數(shù)部分的原型圖
完整的原型鏈查找:
????將Person對象的實例賦值給Student.prototype学搜,所以s1指向的原型對象是Person對象娃善。
????而Person的message()方法則存放在Person的原型對象中论衍,所以s1在調(diào)用方法時,首先在自身的方法中查找聚磺,沒有查找到坯台;繼續(xù)向原型查找,自己的原型上還沒有找到方法瘫寝;那么原型方法又要在自己的原型上繼續(xù)查找蜒蕾,找到message()方法。
????如果還未找到焕阿,即Person的原型對象上還是沒有該方法咪啡,則繼續(xù)想Person原型對象的原型對象查找,查找Object原型對象暮屡,若還沒有撤摸,則查找錯誤。