摘要:原型原型是什么在中函數是一個包含屬性和方法的類型的對象而原型就是類型對象的一個屬性在函數定義時就包含了屬性它的初始值是一個空對象在中并沒有定義函數的原型類型所以原型可以是任何類型原型是用于保存對象的共享屬性和方法的原型的屬性和方法并不會影響
原型 原型是什么
在JavaScript中 函數是一個包含屬性和方法的Function類型的對象 而原型(Prototype)就是Function類型對象的一個屬性
在函數定義時就包含了prototype屬性 它的初始值是一個空對象 在JavaScript中并沒有定義函數的原型類型 所以原型可以是任何類型
原型是用于保存對象的共享屬性和方法的 原型的屬性和方法并不會影響函數本身的屬性和方法
// Function類型的屬性 -> 所有函數都具有的屬性 console.log(Function.prototype); // 定義函數 function fn(){ console.log("this is function"); } // 原型的默認值是空對象 console.log(fn.prototype); // 函數包含構造函數 -> 所有引用類型其實都是構造函數 console.log(Number.prototype); console.log(Object.prototype); var result = Object.getOwnPropertyDescriptor(Object.prototype, "constructor"); console.log(result);獲取原型
function fn(){ console.log("this is function"); } // 使用訪問對象的屬性語法結構 console.log(fn.prototype); console.log(fn["prototype"]); // Object類型提供getPrototypeOf()方法 console.log(Object.getPrototypeOf(fn));為原型新增屬性或者方法
function fn(){ console.log("this is function"); } // 變量proto也是一個空對象 // var proto = fn.prototype; // 新增屬性或方法 // proto.name = "張三"; fn.prototype.name = "張三"; console.log(fn.prototype); // defineProperty() Object.defineProperty(fn.prototype, "age", { value : 28, enumerable : true }); console.log(fn.prototype);構造函數的原型
// 定義構造函數 function Hero(){ this.name = "張三"; this.sayMe = function(){ console.log("this is function"); } } // 操作構造函數Hero的原型 Hero.prototype.age = 28; // 利用構造函數來創建對象 var hero = new Hero(); console.log(hero); // 為構造函數的原型新增的屬性 -> 構造函數創建的對象中依舊可以訪問 console.log(hero.age);// 28 // 對象hero中不存在age屬性 var result = Object.getOwnPropertyDescriptor(hero, "age"); console.log(result);原型屬性 自有屬性與原型屬性
自有屬性:通過對象的引用添加的屬性 其他對象可能無此屬性 即使有 也是彼此獨立的屬性
原型屬性:從原型對象中繼承來的屬性 一旦原型對象中屬性值改變 所有繼承該原型的對象屬性均改變
// 定義構造函數 function Hero(name){ // 構造函數本身的屬性 -> 自有屬性 this.name = name; this.sayMe = function(){ console.log("this is function"); } } // 通過構造函數Hero的prototype新增屬性或方法 // 通過原型所定義的屬性 -> 原型屬性 Hero.prototype.age = 28; /* 通過構造函數Hero創建對象時 * 不僅具有構造函數的自有屬性 * 還具有構造函數的原型屬性 */ var hero = new Hero("張三"); console.log(hero.name);// 張三 console.log(hero.age);// 18 var hero2 = new Hero("李四"); console.log(hero2.name);// 李四 console.log(hero2.age);// 28 // 為對象hero新增age屬性 // hero.age = 80; // console.log(hero.age);// 80 // // console.log(hero); // // console.log(hero2.age);// 28 Hero.prototype.age = 80; console.log(hero.age); console.log(hero2.age);重寫屬性
通過構造函數或對象的自有屬性可以重寫原型的屬性
// 定義構造函數 function Hero(){ this.name = "張三"; } // 構造函數的原型 Hero.prototype.name = "李四"; // 構造函數創建對象 var hero = new Hero(); // 自有屬性與原型屬性同名時,默認訪問的是自有屬性 -> 自有屬性的優先級別高于原型屬性 console.log(hero.name);// 張三 // 刪除對象的屬性 delete hero.name; // 重新訪問對象的屬性 console.log(hero.name);// 李四檢測原型屬性
function Hero(){ //this.name = "張三";// 自有屬性 } //Hero.prototype.name = "李四"; var hero = new Hero(); /* Object.hasOwnProperty(prop)方法 * 作用 - 判斷當前指定屬性是否為自有屬性 * 參數 * prop - 表示指定屬性名稱 * 返回值 - 布爾值 * true - 表示存在指定的自有屬性 * false - 表示不存在指定的自有屬性 */ // console.log(hero.hasOwnProperty("name"));// true /* 使用in關鍵字檢測對象的屬性 * 作用 - 判斷對象中是否存在指定屬性(自有屬性或原型屬性) * 返回值 - 布爾值 * true - 表示存在指定的屬性 * false - 表示不存在指定的屬性 */ console.log("name" in hero);操作原型的方式
// 定義構造函數 function Hero(){} // 通過構造函數的原型新增屬性或方法 // 1.利用對象.屬性或方法的方式新增屬性或方法 Hero.prototype.name = "張三"; Hero.prototype.sayMe = function(){ console.log("this is function"); } // 2.將原型重新賦值為一個新對象 Hero.prototype = { name : "張三", sayMe : function(){ console.log("this is function"); } } // 通過構造函數創建對象 var hero = new Hero(); console.log(hero.name); hero.sayMe();顯式原型與隱式原型
// 定義構造函數 function Hero(){ this.name = "張三"; } // 通過構造函數的原型新增屬性或方法 Hero.prototype.age = 28; // 通過構造函數創建對象 var hero = new Hero(); console.log(hero.name);// 對象調用自有屬性 console.log(hero.age);// 對象調用原型屬性 /* 所有對象其實也具有原型 * 注意 - 對象的原型(__proto__)并非是函數的原型(prototype) * 區分 * 將函數的原型 -> 顯式原型 * 將對象的原型 -> 隱式原型 * 對象的原型 * 不能用于真實開發工作,僅用于邏輯測試 */ console.log(hero.prototype);// undefined 表示對象中不存在該屬性 console.log(hero.__proto__);isPrototypeOf()方法
每個對象中都會具有一個isPrototypeOf()方法 該方法用來判斷一個對象是否是另一個對象的原型
// 通過初始化器方式定義對象 var obj = { name : "張三" } //定義構造函數 function Hero(){} //將對象obj賦值給構造函數Hero的原型 Hero.prototype = obj; //通過構造函數創建對象 var hero = new Hero(); //判斷指定對象是否是另一個對象的原型 var result = obj.isPrototypeOf(hero); console.log(result);擴展內置對象
JavaScript中的內置對象有些也具有prototype屬性 利用內置對象的prototype屬性可以為內置對象擴展屬性或方法
通過原型擴展內置對象的屬性和方法非常靈活 根據個性化要求制定Java Script語言的具體內容
Object.prototype.sayMe = function(){ console.log("this is sayMe function"); } // 通過Object構造函數創建對象 var obj = new Object(); obj.sayMe(); Array.prototype.inArray = function(color){ // this - 表示當前的數組 for(var i = 0, len = this.length; i < len; i++){ if(this[i] === color){ return true; } } return false; } var arr = ["red", "green", "blue"]; console.log(arr.inArray("red")); //true console.log(arr.inArray("yellow")); //false繼承 原型鏈是什么
構造函數或構造器具有prototype屬性 對象具有__proto__屬性 這就是之前學習的原型
如果構造函數或對象A A的原型指向構造函數或對象B B的原型在指向構造函數或對象C 以此類推 最終的構造函數或對象的原型指向Object的原型 由此形成一條鏈狀結構 被稱之為原型鏈
按照上述的描述 在B中定義的屬性或方法 可以直接在A中使用并不需要定義 這就是繼承 它允許每個對象來訪問其原型鏈上的任何屬性或方法
// 原型鏈 function A(){ this.a = "a"; } // 通過構造函數創建對象 var a = new A(); function B(){ this.b = "b"; } // 將B的原型指向對象a B.prototype = a; // 通過構造函數創建對象 var b = new B(); console.log(b.b);// b console.log(b.a);// a function C(){ this.c = "c"; } // 將C的原型指向對象b C.prototype = b; // 通過構造函數創建對象 var c = new C(); console.log(c.c);// c console.log(c.b);// b console.log(c.a);// a只繼承于原型
處于對效率的考慮 盡可能地將屬性和方法添加到原型上
1.不要為繼承關系多帶帶創建新對象
2.盡量減少運行時的方法搜索
// 原型鏈 function A(){ // 將自有屬性改寫為原型屬性 // this.a = "a"; } A.prototype.a = "a"; function B(){ // this.b = "b"; } // 將B的原型指向 B.prototype = A.prototype; B.prototype.b = "b"; /*B.prototype = { b : "b" }*/ function C(){ this.c = "c"; } // 將C的原型指向 C.prototype = B.prototype; var c = new C(); console.log(c.c);// c console.log(c.b); console.log(c.a);// a原型鏈實現繼承的問題
// 原型鏈 function A(){ // 將自有屬性改寫為原型屬性 // this.a = "a"; } A.prototype.a = "a"; function B(){ // this.b = "b"; } // 將B的原型指向 B.prototype = A.prototype; B.prototype.b = "b"; function C(){ // this.c = "c"; } // 將C的原型指向 C.prototype = B.prototype; C.prototype.c = "c"; var c = new C(); console.log(c.c);// c console.log(c.b);// b console.log(c.a);// a var a = new A(); console.log(a.a); console.log(a.b); console.log(a.c); var b = new B(); console.log(b.a); console.log(b.b); console.log(b.c);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108285.html
摘要:綜上所述有原型鏈繼承,構造函數繼承經典繼承,組合繼承,寄生繼承,寄生組合繼承五種方法,寄生組合式繼承,集寄生式繼承和組合繼承的優點于一身是實現基于類型繼承的最有效方法。 一、前言 繼承是面向對象(OOP)語言中的一個最為人津津樂道的概念。許多面對對象(OOP)語言都支持兩種繼承方式::接口繼承 和 實現繼承 。 接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。由于js中方法沒有簽名...
摘要:在節中,我們學習到了通過構造函數創建對象的三個重要步驟,其中的一步是把構造函數的對象設置為創建對象的原型。利用而不是直接用創建一個實例對象的目的是,減少一次調用父構造函數的執行。 JavaScript語言不像面向對象的編程語言中有類的概念,所以也就沒有類之間直接的繼承,JavaScript中只有對象,使用函數模擬類,基于對象之間的原型鏈來實現繼承關系,ES6的語法中新增了class關鍵...
摘要:原型對象是由創建的,因此原型對象的構造函數是構造函數也可以是稱為對象,原型對象也就繼承了其生父構造函數中的數據,也同時繼承了原型對象的數據。當然這條原型鏈中的數據,會被還是還是這類構造函數繼承,但是不會被這些繼承,他們不處于同一個鏈條上。 js中,Function的本質是什么?Object的本質又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
摘要:當然這還沒完,因為我們還有重要的一步沒完成,沒錯就是上面的第行代碼,如果沒有這行代碼實例中的指針是指向構造函數的,這樣顯然是不對的,因為正常情況下應該指向它的構造函數,因此我們需要手動更改使重新指向對象。 第一節內容:javaScript原型及原型鏈詳解(二) 第一節中我們介紹了javascript中的原型和原型鏈,這一節我們來講利用原型和原型鏈我們可以做些什么。 普通對象的繼承 ...
摘要:每一個由構造函數創建的對象都會默認的連接到該神秘對象上。在構造方法中也具有類似的功能,因此也稱其為類實例與對象實例一般是指某一個構造函數創建出來的對象,我們稱為構造函數的實例實例就是對象。表示該原型是與什么構造函數聯系起來的。 本文您將看到以下內容: 傳統構造函數的問題 一些相關概念 認識原型 構造、原型、實例三角結構圖 對象的原型鏈 函數的構造函數Function 一句話說明什么...
閱讀 1362·2021-11-22 15:25
閱讀 3354·2021-10-21 09:38
閱讀 1572·2021-10-19 13:21
閱讀 998·2021-09-06 15:00
閱讀 1678·2019-08-30 15:44
閱讀 2591·2019-08-29 15:40
閱讀 3444·2019-08-29 13:44
閱讀 2047·2019-08-26 16:56