導航:首頁 > 編程語言 > js原型對象與原型鏈

js原型對象與原型鏈

發布時間:2023-02-03 15:51:45

Ⅰ 談談對原型鏈的理解 js原型鏈怎麼理解

js對象是由構來造方法創建源的,構造方法有個原型prototype,那麼對象和原型之間的關系就叫做原型鏈。例如用原型給對象定義方法obj.prototype.funName = function(){alert("我是原型的方法")};對象可以直接從原型中調用這個方法obj.funName();更多JS深層知識可以進群前面是二九6中間是5九一後面是二九零,每天分享JS深層技術。

Ⅱ js中什麼是原型對象和原型鏈

每個 javaScript 對象內部都有一個指向其它對象的「指針」或者 「引用「, 並通過這種方式在對象之專間建立了一屬種聯系,形成了一種鏈式結構,我的理解這就是所謂的原型鏈。

functionF(){}//F是一個函數,函數也是對象,而且每個函數都有一個屬性叫:"prototype"
varo=newF();//F.prototype就是o的原型對象

console.log(o.name);
//輸出:undefined

F.prototype.name="foo";
console.log(o.name);
//輸出:foo


//上面這個例子是想說明:通過new在對象o與對象F.prototype之間建立了聯系,這個建立聯系
//的方式有人叫"原型繼承"。當訪問的對象屬性不存在時,就會沿著原型鏈去查找。

Ⅲ javascript原型,原型鏈 有什麼特點

javascript原型,原型鏈特點:原型鏈實現了繼承。

JS中每個函數都存在有一個原型對象屬性prototype。並且所有函數的默認原型都是Object的實例。每個繼承父函數的子函數的對象都包含一個內部屬性proto。該屬性包含一個指針,指向父函數的prototype。若父函數的原型對象的_proto_屬性為再上一層函數。在此過程中就形成了原型鏈。

原型鏈的作用是用來實現繼承,比如我們新建一個數組,數組的方法就是從數組的原型上繼承而來的。

var arr = [];

arr.map === Array.prototype.map //arr.map

是從arr.__proto__上繼承下來的,arr.__proto__也就是Array.prototype。

(3)js原型對象與原型鏈擴展閱讀:

1.JS中每個函數都存在有一個原型對象屬性prototype。並且所有函數的默認原型都是Object的實例。

2.每個繼承父函數的子函數的對象都包含一個內部屬性_proto_。該屬性包含一個指針,指向父函數的prototype。若父函數的原型對象的_proto_屬性為再上一層函數。在此過程中就形成了原型鏈。

3.原型鏈實現了繼承。原型鏈存在兩個問題:a 包含引用類型值的原型屬性會被所有實例共享。b 在創建子類型時,無法向超類型的構造函數中傳遞參數。

參考資料:網路-javascript

Ⅳ JavaScript原型,原型鏈 有什麼特點

1.1 一切皆為對象
JavaScript里所有的東西都是對象. 對象是屬性的集合. 數字, 字元串, 布爾值等原始值是"偽對象", 它們同樣擁有屬性, 但是是在棧上分配並按值傳遞. 而其他的對象是堆上分配並按引用傳遞.
一個很重要的概念是,函數也是對象, 能夠作為變數的值, 返回值, 參數或者屬性的值. 函數對象特殊的地方是能通過"xxx()"語法執行包含在xxx函數對象內的代碼. 因為這一特殊性, typeof xxx 將會返回function, 但這只是一種便利設施.

1.2 對象的屬性可以動態添加和刪除

varfoo=newObject();
//為foo對象添加bar屬性
foo.bar="foobar";
alert(foo.bar);//foobar
//刪除foo對象的bar屬性
deletefoo.bar;
alert(foo.bar);//undefined


1.3 除了宿主對象, 其它對象皆由構造函數創建
要有對象, 就先要有創建對象的方法.
在C++/Java等語言, 這個方法就是實例化XXX類的一個實例xxx.
而在JavaScript的世界裡實際沒有類的東西, 當然仍然可以用"類"和"實例"等慣用語來描述JavaScript中類似的行為, 但其機制是完全不同的. JavaScript的對象是由構造函數創建的, 每個對象都有constructor屬性表示創建該對象的構造函數:

functionTest(){this.a="hello";}
vartest=newTest();//由Test構造函數創建
alert(test.constructor);

varo={a:"hello"};
//實際相當於
varo_=newObject();
o_.a="hello";//由Object構造函數創建
alert(o.constructor);

構造函數也是對象, 那構造函數是由什麼創建? 內建的Function函數:

functionTest(a, b)
{
alert(a+b);
}
//相當於:
Test=newFunction(["a","b"],"alert(a+b);");

Function函數又是由什麼創建? 實際上Function是本機代碼實現的固有對象. 不過為了一致性, Function也有constructor屬性, 該屬性指向它自己. 接上面的代碼:

/*輸出functionFunction(){
[nativecode]
}
*/
alert(Test.constructor);

alert(Test.constructor.constructor===Test.constructor);//true
alert(Test.constructor===Object.constructor);//true


2 原型prototype
2.1 prototype的概念
prototype是構造函數的一個屬性, 該屬性指向一個對象. 而這個對象將作為該構造函數所創建的所有實例的基引用(base reference),可以把對象的基引用想像成一個自動創建的隱藏屬性. 當訪問對象的一個屬性時, 首先查找對象本身, 找到則返回; 若不, 則查找基引用指向的對象的屬性(如果還找不到實際上還會沿著原型鏈向上查找, 直至到根).只要沒有被覆蓋的話, 對象原型的屬性就能在所有的實例中找到.
原型默認為Object的新實例, 由於仍是對象, 故可以給該對象添加新的屬性:

//prototype默認為newObject();為了方便, 記為p_obj
functionPerson(name){
this.name=name;
}

//為p_obj增加sayName屬性
Person.prototype.sayName=function(){
alert(this.name);
}

varjohn=newPerson("John");//john的basereference指向p_obj
vareric=newPerson("Eric");//eric的basereference也是指向p_obj

//注意sayName代碼中的this將指向實例化後的對象(this綁定)
john.sayName();//john對象本身沒有sayName屬性,於是訪問原型對象p_obj的sayName屬性
eric.sayName();//訪問同一個原型對象p_obj的sayName屬性


vartmp=Person.prototype;
tmp.boss="David";
//於這個運行點,p_obj已經被修改
//根據上述屬性訪問流程,新的修改(boss屬性)能反映到所有的實例,包括已經創建和即將創建的
alert("John'sbossis"+john.boss);
alert("Eric'sbossis"+eric.boss);


//hisCar和sayCar屬性將增加到john對象而不是p_obj對象..
john.hisCar="Audi";
john.sayCar=function(){
alert(this.name+"hasacarof"+this.hisCar);
}
john.sayCar();
//..因此下一句將錯誤,因為eric對象本身和原型p_obj都沒有sayName屬性
/*eric.sayCar();*/


2.2 原型鏈
除了能修改prototype指向的對象, 還能修改prototype指向哪一個對象, 即為prototype賦予一個不同的對象. 這可以實現一種簡單的繼承:

functionSuperman(){}
Superman.prototype.sayHello=function(){
alert("I'masuperman.");
}

functionSupermanCan(skill){
this.skill=skill;
}
//為prototype賦予Superman的實例..
SupermanCan.prototype=newSuperman();
//..再動態添加新的屬性
SupermanCan.prototype.sayMore=function(){
this.sayHello();//調用"父類"的方法
alert("Ican"+this.skill);
}

vardavid=newSupermanCan("fly");
//output:I'masuperman.Icanfly
david.sayMore();

如果先實例化出一個對象, 再為構造函數prototype賦予一個不同的對象, 將會: 已經創建的對象的基引用不變, 將來創建的對象的基引用為新的原型對象:

varf1={echo:function(){alert("sound");}};
functionFoo(){};
varfoo=newFoo();//foo的基引用指向Object實例
Foo.prototype=f1;
/*未定義,因為這是"foo對象自己或者基引用指向的對象有echo屬性嗎?"
而不是"foo對象自己或者Foo.prototype指向的對象有echo屬性嗎?"*/
alert(foo.echo);

varfoo2=newFoo();//foo2的基引用指f1對象
foo2.echo();//output:sound

所有的構造函數的prototype都不能為空, 就是說Superman.prototype = null 會被解釋引擎無視; 另一方面, Object構造函數也有prototype屬性(該屬性是只讀的, 可以為原型增加屬性,但不能賦予不同的對象), 故因此可以有多層的原型鏈, 但原型鏈的根必定會是Object.prototype . 這意味著給Object.prototype增加屬性影響到所有對象:

Object.prototype.echo=function(){
alert("hello");
}

//echo屬性將增加到所有對象固有對象和自定義對象

vararr=newArray();
arr.echo();
Array.echo();

functionObjCons(){
this.mmy="d";
}
varobj=newObjCons();
obj.echo();
ObjCons.echo();


3. 構造函數和new的實質
構造函數是一個地地道道的函數, 一個函數之所以能成為構造函數, 是因為new運算符:

this.msg="window";

functionTest()
{
alert(this.msg);
}

Test();//window
vartest=newTest();//undefined.因為test對象沒有定義msg屬性

二者區別在於如何切入對象: Test() 在某個對象(例子中為window)的上下文上執行代碼, 即this指向這個對象; new Test()創建一個新對象, 並以這個新的對象為上下文(this指向新對象)執行代碼, 然後返回這個新對象.
假如有個函數:

functionTest(){
varmmy="havemoney";
this.wish=mmy;
doSomeThing();

}

結合以上的所有論述, 可以推測new Test()行為的偽代碼表示為:
創建一個新對象temp;
temp.constructor = Test;
temp.(base reference) = Test.prototype; // 這一句先於代碼體執行, 意味著構造函數里的this.xxx能訪問原型對象的屬性xxx
bind: this=temp; //將this綁定到temp對象
// 開始執行函數代碼
var mmy = "have money";
this.wish = mmy; // 為temp對象添加wish屬性
doSomeThing();
....
// 結束執行函數代碼
return temp;
這個未必會符合內部的二進制實現, 但卻能很好地解釋了JavaScript的特性.

閱讀全文

與js原型對象與原型鏈相關的資料

熱點內容
vhd文件有什麼用 瀏覽:482
編程小朋友看什麼書 瀏覽:623
經營如何讓數據說話 瀏覽:258
如何在手機上升級opop 瀏覽:614
coreldrawx5免費視頻教程 瀏覽:725
網站引導頁面源碼 瀏覽:234
個人簡歷範文word 瀏覽:220
uc下載的視頻怎樣提取到文件 瀏覽:499
英雄下載下載最新版本2015下載安裝 瀏覽:433
NX深孔鑽編程替換面如何操作 瀏覽:725
手機怎麼刪除pdf文件 瀏覽:256
蘋果手機沒有efs文件夾怎麼辦 瀏覽:723
metro軟體在哪個文件夾 瀏覽:69
怎麼用手機登錄編程貓 瀏覽:400
文本md204顯示器如何編程 瀏覽:705
如何將表中重復數據標記 瀏覽:859
中級資料庫系統工程師應用技術考什麼 瀏覽:404
博途編程如何設置停止鍵 瀏覽:409
python3刪除文件內容 瀏覽:754
如何優化seo數據分析 瀏覽:132

友情鏈接