天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

前端開發必須知道的JS之原型和繼承

一. 原型與構造函數

  Js所有的函數都有一個prototype屬性,這個屬性引用了一個對象,即原型對象,也簡稱原型。這個函數包括構造函數和普通函數,我們講的更多是構造函數的原型,但是也不能否定普通函數也有原型。譬如普通函數:
復制代碼 代碼如下:
function F(){
  alert(F.prototype instanceof Object) //true;
}


  構造函數,也即構造對象。首先了解下通過構造函數實例化對象的過程。
復制代碼 代碼如下:
function A(x){
  this.x=x;
}
var obj=new A(1);


實例化obj對象有三步:

  1. 創建obj對象:obj=new Object();

  2. 將obj的內部__proto__指向構造他的函數A的prototype,同時,obj.constructor===A.prototype.constructor(這個是永遠成立的,即使A.prototype不再指向原來的A原型,也就是說:類的實例對象的constructor屬性永遠指向"構造函數"的prototype.constructor),從而使得obj.constructor.prototype指向A.prototype(obj.constructor.prototype===A.prototype,當A.prototype改變時則不成立,下文有遇到)。obj.constructor.prototype與的內部_proto_是兩碼事,實例化對象時用的是_proto_,obj是沒有prototype屬性的,但是有內部的__proto__,通過__proto__來取得原型鏈上的原型屬性和原型方法,FireFox公開了__proto__,可以在FireFox中alert(obj.__proto__);

  3. 將obj作為this去調用構造函數A,從而設置成員(即對象屬性和對象方法)并初始化。

  當這3步完成,這個obj對象就與構造函數A再無聯系,這個時候即使構造函數A再加任何成員,都不再影響已經實例化的obj對象了。此時,obj對象具有了x屬性,同時具有了構造函數A的原型對象的所有成員,當然,此時該原型對象是沒有成員的。

  原型對象初始是空的,也就是沒有一個成員(即原型屬性和原型方法)。可以通過如下方法驗證原型對象具有多少成員。
復制代碼 代碼如下:
var num=0;
for(o in A.prototype) {
  alert(o);//alert出原型屬性名字
  num++;
}
alert("member: " + num);//alert出原型所有成員個數。


  但是,一旦定義了原型屬性或原型方法,則所有通過該構造函數實例化出來的所有對象,都繼承了這些原型屬性和原型方法,這是通過內部的_proto_鏈來實現的。

  譬如

  A.prototype.say=function(){alert("Hi")};

  那所有的A的對象都具有了say方法,這個原型對象的say方法是唯一的副本給大家共享的,而不是每一個對象都有關于say方法的一個副本。

二. 原型與繼承

  首先,看個簡單的繼承實現。
復制代碼 代碼如下:
function A(x){
  this.x=x;
}
function B(x,y){
  this.tmpObj=A;
  this.tmpObj(x);
  delete this.tmpObj;
  this.y=y;
}


  第5、6、7行:創建臨時屬性tmpObj引用構造函數A,然后在B內部執行,執行完后刪除。當在B內部執行了this.x=x后(這里的this是B的對象),B當然就擁有了x屬性,當然B的x屬性和A的x屬性兩者是獨立,所以并不能算嚴格的繼承。第5、6、7行有更簡單的實現,就是通過call(apply)方法:A.call(this,x);

這兩種方法都有將this傳遞到A的執行里,this指向的是B的對象,這就是為什么不直接A(x)的原因。這種繼承方式即是類繼承(js沒有類,這里只是指構造函數),雖然繼承了A構造對象的所有屬性方法,但是不能繼承A的原型對象的成員。而要實現這個目的,就是在此基礎上再添加原型繼承。


  通過下面的例子,就能很深入地了解原型,以及原型參與實現的完美繼承。(本文核心在此^_^)
復制代碼 代碼如下:
function A(x){
  this.x = x;
}
A.prototype.a = "a";
function B(x,y){
  this.y = y;
  A.call(this,x);
}
B.prototype.b1 = function(){
  alert("b1");
}
B.prototype = new A();
B.prototype.b2 = function(){
  alert("b2");
}
B.prototype.constructor = B;
var obj = new B(1,3);

  這個例子講的就是B繼承A。第7行類繼承:A.call(this.x);上面已講過。實現原型繼承的是第12行:B.prototype = new A();

  就是說把B的原型指向了A的1個實例對象,這個實例對象具有x屬性,為undefined,還具有a屬性,值為"a"。所以B原型也具有了這2個屬性(或者說,B和A建立了原型鏈,B是A的下級)。而因為方才的類繼承,B的實例對象也具有了x屬性,也就是說obj對象有2個同名的x屬性,此時原型屬性x要讓位于實例對象屬性x,所以obj.x是1,而非undefined。第13行又定義了原型方法b2,所以B原型也具有了b2。雖然第9~11行設置了原型方法b1,但是你會發現第12行執行后,B原型不再具有b1方法,也就是obj.b1是undefined。因為第12行使得B原型指向改變,原來具有b1的原型對象被拋棄,自然就沒有b1了。

  第12行執行完后,B原型(B.prototype)指向了A的實例對象,而A的實例對象的構造器是構造函數A,所以B.prototype.constructor就是構造對象A了(換句話說,A構造了B的原型)。

alert(B.prototype.constructor)出來后就是"function A(x){...}" 。同樣地,obj.constructor也是A構造對象,alert(obj.constructor)出來后就是"function A(x){...}" ,也就是說B.prototype.constructor===obj.constructor(true),但是B.prototype===obj.constructor.prototype(false),因為前者是B的原型,具有成員:x,a,b2,后者是A的原型,具有成員:a。如何修正這個問題呢,就在第16行,將B原型的構造器重新指向了B構造函數,那么B.prototype===obj.constructor.prototype(true),都具有成員:x,a,b2。

  如果沒有第16行,那是不是obj = new B(1,3)會去調用A構造函數實例化呢?答案是否定的,你會發現obj.y=3,所以仍然是調用的B構造函數實例化的。雖然obj.constructor===A(true),但是對于new B()的行為來說,執行了上面所說的通過構造函數創建實例對象的3個步驟,第一步,創建空對象;第二步,obj.__proto__ === B.prototype,B.prototype是具有x,a,b2成員的,obj.constructor指向了B.prototype.constructor,即構造函數A;第三步,調用的構造函數B去設置和初始化成員,具有了屬性x,y。雖然不加16行不影響obj的屬性,但如上一段說,卻影響obj.constructor和obj.constructor.prototype。所以在使用了原型繼承后,要進行修正的操作。

  關于第12、16行,總言之,第12行使得B原型繼承了A的原型對象的所有成員,但是也使得B的實例對象的構造器的原型指向了A原型,所以要通過第16行修正這個缺陷。

  畢了。

JavaScript技術前端開發必須知道的JS之原型和繼承,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 日韩精品 电影一区 亚洲高清 | 狠狠综合久久综合88亚洲 | 色欲狠狠躁天天躁无码中文字幕 | 忘忧草高清 | 日本高清免费一本在线观看 | 两个女人互添下身高潮自视频 | 久草精品在线 | 旧里番6080在线观看 | 久久精品视在线-2 | 美女被抽插到哭内射视频免费 | 大胸美女被吊起来解开胸罩 | 伊人yinren6综合网色狠狠 | 九九热免费在线观看 | 九九久久国产精品免费热6 九九久久国产精品大片 | 亚州中文字幕 | 秘密教学93话恩爱久等了免费 | 精品亚洲永久免费精品 | 999www成人免费视频 | 丝瓜视频樱桃视频在线观看免费 | 视频在线免费观看 | 嗯 用力啊 嗯 c我 啊哈老师 | 暖暖视频免费观看高清完整版 | 无码人妻丰满熟妇啪啪网不卡 | 日本真人啪啪试看30秒 | 国产在线精品亚洲第1页 | 午夜黄视频 | 欧美一道本一区二区三区 | 男女车车的车车网站W98免费 | 果冻传媒APP免费网站在线观看 | 黑吊大战白女出浆 | a视频在线免费观看 | 艳鉧动漫片1~6全集在线 | 国产真实露脸乱子伦 | 美女搞鸡网站 | 三级黄色高清视频 | 久久国产成人午夜AV影院无码 | 极品少妇高潮啪啪AV无码 | 欧美人与动牲交A免费 | 国产精品久久久久久久久LI无码 | 青青视频国产依人在线 | 狂野欧美性猛XXXX乱大交 |