国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解JavaScript中基于原型prototype的繼承特性

2019-11-20 10:09:11
字體:
來源:轉載
供稿:網友

JavaScript 中的繼承比較奇葩,無法實現接口繼承,只能依靠原型繼承。

原型鏈
原型就是一個對象,通過構造函數創建出來的實例會有指針指向原型得到原型的屬性和方法。這樣,實例對象就帶有構造函數的屬性方法和原型的屬性方法,然后將需要繼承的構造函數的原型指向這個實例,即可擁有這個實例的所有屬性方法實現繼承。
看下面演示代碼:

//聲明超類,通過構造函數和原型添加有關屬性和方法function Super(){  this.property = true;}Super.prototype.getSuperValue = function() {  return this.property;};//聲明子類的構造函數function SubType() {  this.subproperty = false;}//將子類的原型指向超類的實例,得到超類的一切SubType.prototype = new Super();SubType.prototype.constructor = SubType;SubType.prototype.getSubValue = function(){  return this.subproperty;};//由子類創建對象,測試是否繼承超類方法和屬性var instance = new SubType();console.log(instance.getSuperValue());

所有函數的默認原型都是 Object 的實例,因此默認原型都會包含一個內部指針,指向 Object.prototype。
使用 instanceof 和 isPrototypeOf 可以確定原型和實例的關系:

instance instanceof Object;Object.prototype.isPrototypeOf(instance);

使用原型鏈的時候,需要謹慎的定義方法。子類需要重寫超類型的某個方法或者擴充,一定要放在替換原型的語句后面,這樣才能生效。此外,通過原型鏈實現繼承時,不能使用對象字面量創建原型方法,這樣會重寫原型鏈:

......SubType.prototype = new Super();SubType.prototype = {  ....};

這會更換指針指向新對象,從而重寫了原型鏈。
原型鏈的繼承方法是有缺陷的,主要有兩個問題:
1,來自包含引用類型值的原型,會被所有實例共享。
前面文章介紹過包含引用類型值的原型屬性會被所有實例共享,一個實例修改,其他實例會隨之改變,因此需要在構造函數中定義屬性。而原型鏈繼承的時候,無論超類中屬性是在構造函數還是原型中定義,全部都變成了實例對象被子類繼承,從而對子類的實例產生影響。
2,創建子類型的實例時,不能向超類型的構造函數中傳遞參數。
原型鏈的繼承,直接將子類原型指向超類的實例,這時候可以向超類傳遞參數。但是當子類創建實例的時候,只能向子類的構造函數傳遞參數,而不能向超類的構造函數傳遞參數。
因此實際應用中,很少單獨使用原型鏈。

相關的一些代碼實踐

鑒別一個原型屬性

function hasPrototypeProperty(object, name) {  return name in object && !object.hasOwnProperty(name);}

在構造函數中使用原型對象

function Person(name) {  this.name = name;}Person.prototype = {  constructor: Person,  sayName: function () {    console.log(this.name);  },  toString: function() {  }};var person1 = new Person('Nicholas');var person2 = new Person('Greg);console.log(person1 instanceof Person); // trueconsole.log(person1.constructor === Person); // trueconsole.log(person1.constructor === Object); // falseconsole.log(person2 instanceof Person); // trueconsole.log(person2.constructor === Person); // trueconsole.log(person2.constructor === Object); // false

對象繼承

var person1 = {  name: 'Nicholas',  sayName: function () {    console.log(this.name);  }};var person2 = Object.create(person1, {  name: {    configurable: true,    enumerable: true,    value: 'Greg',    writable: true  }});person1.sayName(); // Nicholasperson2.sayName(); // Gregconsole.log(person1.hasOwnProperty('sayName')); // trueconsole.log(person1.isPropertyOf(person2)); // trueconsole.log(person2.hasOwnProperty('sayName')); // false

模塊模式

var person = (function () {  var age = 25;  function getAge() {    return age;  }  function growOlder() {    age++;  }  return {    name: 'Nicholas',    getAge: getAge,    growOlder: growOlder  };}());

作用域的構造函數

function Person(name) {  this.name = name;}Person.prototype.sayName = function() {  console.log(this.name);};var person1 = Person('Nicholas');console.log(person1 instanceof Person); // falseconsole.log(typeof person1); // undefinedconsole.log(name); // Nicholas
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 锡林浩特市| 东光县| 称多县| 乌拉特中旗| 大名县| 营口市| 历史| 禄丰县| 沙河市| 临海市| 磐安县| 广元市| 北海市| 石首市| 仁寿县| 长治市| 永兴县| 阿瓦提县| 缙云县| 佳木斯市| 安陆市| 伊川县| 勐海县| 清流县| 南雄市| 伊通| 永胜县| 铁岭县| 宿松县| 贞丰县| 铁岭市| 额尔古纳市| 楚雄市| 西吉县| 朝阳区| 青阳县| 浦东新区| 衡南县| 加查县| 监利县| 南召县|