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

首頁 > 網站 > WEB開發 > 正文

ES5和ES6中對于繼承的實現方法

2024-04-27 15:15:56
字體:
來源:轉載
供稿:網友

在ES5繼承的實現非常有趣的,由于沒有傳統面向對象類的概念,javascript利用原型鏈的特性來實現繼承,這其中有很多的屬性指向和需要注意的地方。

原型鏈的特點和實現已經在之前的一篇整理說過了,就是通過將子類構造函數的原型作為父類構造函數的實例(sub.PRototype=new super),這樣就連通了子類-子類原型-父類,原型鏈的特點就是逐層查找,從子類開始一直往上直到所有對象的原型Object.prototype,找到屬性方法之后就會停止查找,所以下層的屬性方法會覆蓋上層。

一個基本的基于原型鏈的繼承過程大概是這樣的:

//先來個父類,帶些屬性function Super(){    this.flag = true;}//為了提高復用性,方法綁定在父類原型屬性上Super.prototype.getFlag = function(){    return this.flag;}//來個子類function Sub(){    this.subFlag = false;}//實現繼承Sub.prototype = new Super;//給子類添加子類特有的方法,注意順序要在繼承之后Sub.prototype.getSubFlag = function(){    return this.subFlag;}//構造實例var es5 = new Sub;原型鏈實現的繼承主要有幾個問題:1、本來我們為了構造函數屬性的封裝私有性,方法的復用性,提倡將屬性聲明在構造函數內,而將方法綁定在原型對象上,但是現在子類的原型是父類的一個實例,自然父類的屬性就變成子類原型的屬性了;這就會帶來一個問題,我們知道構造函數的原型屬性在所有構造的實例中是共享的,所以原型中屬性的改變會反應到所有的實例上,這就違背了我們想要屬性私有化的初衷;2、創建子類的實例時,不能向父類的構造函數傳遞參數

function Super(){    this.flag = true;}function Sub(){   this.subFlag = false;}Sub.prototype = new Super;var obj = new Sub();obj.flag = flase;  //修改之后,由于是原型上的屬性,之后創建的所有實例都會受到影響var obj_2 = new Sub();console.log(obj.flag)  //false;

為了解決以上兩個問題,有一個叫借用構造函數的方法只需要在子類構造函數內部使用apply或者call來調用父類的函數即可在實現屬性繼承的同時,又能傳遞參數,又能讓實例不互相影響

function Super(){    this.flag = true;}function Sub(){    Super.call(this)  //如果父類可以需要接收參數,這里也可以直接傳遞}var obj = new Sub();obj.flag = flase;var obj_2 = new Sub();console.log(obj.flag)  //依然是true,不會相互影響結合借用構造函數和原型鏈的方法,可以實現比較完美的繼承方法,可以稱為組合繼承:

function Super(){    this.flag = true;}Super.prototype.getFlag = function(){    return this.flag;     //繼承方法}function Sub(){    this.subFlag = flase    Super.call(this)    //繼承屬性}Sub.prototype = new Super;var obj = new Sub();Sub.prototype.constructor = Sub;Super.prototype.getSubFlag = function(){    return this.flag;}
function Box(age) {this.name = ['Lee', 'Jack', 'Hello']this.age = age;}Box.prototype.run = function () {return this.name + this.age;};function Desk(age) {Box.call(this, age); //對象冒充}Desk.prototype = new Box(); //原型鏈繼承var desk = new Desk(100);alert(desk.run());

這里還有個小問題,Sub.prototype = new Super; 會導致Sub.prototype的constructor指向Super;然而constructor的定義是要指向原型屬性對應的構造函數的,Sub.prototype是Sub構造函數的原型,所以應該添加一句糾正:Sub.prototype.constructor = Sub;

看完ES5的實現,再來看看ES6的繼承實現方法,其內部其實也是ES5組合繼承的方式,通過call借用構造函數,在A類構造函數中調用相關屬性,再用原型鏈的連接實現方法的繼承

class B extends A {  constructor() {    return A.call(this);  //繼承屬性  }}A.prototype = new B;  //繼承方法ES6封裝了class,extends關鍵字來實現繼承,內部的實現原理其實依然是基于上面所講的原型鏈,不過進過一層封裝后,Javascript的繼承得以更加簡潔優雅地實現

class ColorPoint extends Point {  constructor(x, y, color) {    super(x, y); // 等同于parent.constructor(x, y)    this.color = color;  }  toString() {    return this.color + ' ' + super.toString(); // 等同于parent.toString()  }}通過constructor來定義構造函數,用super調用父類的屬性方法

轉至:http://www.jianshu.com/p/342966fdf816


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临潭县| 体育| 塔城市| 新源县| 迭部县| 富源县| 治多县| 信阳市| 凤冈县| 玛纳斯县| 湘潭市| 泸西县| 汕头市| 丹江口市| 民乐县| 枝江市| 天台县| 科技| 尚志市| 磐石市| 临夏县| 陈巴尔虎旗| 江口县| 沙田区| 仙居县| 桃江县| 西乌| 朝阳县| 牟定县| 哈巴河县| 朔州市| 昌邑市| 邓州市| 汕尾市| 连城县| 安徽省| 白水县| 广元市| 东乌珠穆沁旗| 永修县| 博兴县|