聊一聊Javasript繼承

来源:https://www.cnblogs.com/moyhui/archive/2018/01/18/8308994.html
-Advertisement-
Play Games

  前前後後已經快寫了2年左右javaScript,剛開始只是簡單用於一些表單驗證和操作dom節點,並沒有深入的使用,隨著漸漸的深入,開始不想去寫重覆的代碼(懶的開始),從而寫簡單的繼承,封裝,抽象等等,最終效果寫重覆代碼少、可用性高(主要:迭代快、代碼可以持續使用, 加班 也少 ...


  前前後後已經快寫了2年左右javaScript,剛開始只是簡單用於一些表單驗證和操作dom節點,並沒有深入的使用,隨著漸漸的深入,開始不想去寫重覆的代碼(懶的開始),從而寫簡單的繼承,封裝,抽象等等,最終效果寫重覆代碼少、可用性高(主要:迭代快、代碼可以持續使用,加班也少)

Demo構造函數聲明類

function Person(name){
    this.name = name;
}
new生成實例

new生成實例的缺點:無法共用屬性和方法,每次new新的實例會開闢新的記憶體空間,造成極大的資源浪費。

var personA = new Person('小明');
console.log(personA.name);

構造函數的this指向新的實例
如:

function Person(name){
    this.name = name;
    this.sex = '女'
}

var personA = new Person('小明');
var personB = new Person('小妞');
personA.sex = '男';
console.log(personB.sex);  //女

在這裡我們該採用聲明解決方案呢?設計者很好的解決了這個問題,那麼就是prototype屬性(包含對象)的引入

prototype屬性

它的好處是,實例一旦創建,將自動共同持有共用屬性和方法,如:

function Person(name){
    this.name = name;
}
Person.prototype.sex = '女';
var personA = new Person('小明');
var personB = new Person('小妞');
console.log(personA.sex);  //女
console.log(personB.sex);  //女

//證明它們是共用的
Person.prototype.sex = '男';
console.log(personA.sex);  //男
console.log(personB.sex);  //男

也許在這裡你看不出prototype的好處,但是當你有很多方法和屬性時,你的運行效率還高嘛?那麼:

function Person(name, sex){
    this.name = name;
    this.sex = sex,
    this.country = '中國',
    this.show = function(){
        console.log(this.name + '的國籍是:'+this.country+',性別:'+this.sex);
    }
}
var personA = new Person('小明'.'男');
personA.show();   //小明的國籍是是中國,性別:男
var personB = new Person('小妞','女');
personB.show();  //小妞的國籍是是中國,性別:女

感覺似乎沒有什麼問題,但是personA和personB都包含有country、show屬性方法一模一樣的內容,這樣就造成了空間的浪費,效率也降低了,那麼我們可以它們共用屬性和方法

function Person(name, sex){
    this.name = name;
    this.sex = sex,
}

Person.prototype.country = '中國';
Person.prototype.show = function(){
    console.log(this.name + '的國籍是:'+this.country+',性別:'+this.sex);
}

var personA = new Person('小明'.'男');
var personB = new Person('小妞','女');
personA.show();   //小明的國籍是是中國,性別:男
personB.show();  //小妞的國籍是是中國,性別:女

配合protorype使用的屬性--isPrototypeOf(),hasOwnPrototype(),in

function Person(name, sex){
    this.name = name;
    this.sex = sex,
}

Person.prototype.country = '中國';
Person.prototype.show = function(){
    console.log(this.name + '的國籍是:'+this.country+',性別:'+this.sex);
}

//isPrototypeOf() 判斷實例和對象之間的關係
console.log(Person.prototype.isPrototype(personA))  //true
console.log(Person.prototype.isPrototype(personB))  //true

//hasOwnPrototype() 判斷屬性是本地屬性,還是繼承自prototype屬性
console.log(personA.hasOwnPrototy('name'))  //true
console.log(personA.hasOwnPrototy('country'))  //false

//in 判斷是否含有屬性,不管本地還是繼承prototype
console.log('name' in personA)  //true
console.log('country' in personA)  //true

constructor屬性

繼續使用前面Person原型對象

function Person(name){
    this.name = name;
}
Person.prototype.sex = '女';
var personA = new Person('小明');
var personB = new Person('小妞');
//新增的實例自動包含有constructor屬性
console.log(personA.constructor == Person);  //true
console.log(personB.constructor == Person);  //true

這裡也可以使用instanceof判斷實例和原型對象之間的關係

console.log(personA instanceof Person);  //true
console.log(personB instanceof Person);  //true

常用Object之間“繼承”(構造函數繼承)(5種)

假設現在有Person和Teacher兩個Object,想讓Teacher繼承Person

//Person對象
function Person(name){
    this.name = name;
}

//Teacher對象
function Teacher(age,sex){
    this.age = age;
    this.sex = sex;
}
1、利用構造函數綁定(call或者apply)
function Teacher(age,sex,name){
    Person.apply(this,name);//Person.call(this,name);
    this.age = age;
    this.sex =sex;
}
2、使用prototype,也就是我們前面說prototype屬性,修改constructor指向
Teacher.prototype = new Person('xiaoming'); //修改prototy對象原先的值
Teacher.prototype.constructor = Teacher;
var teacher1 = new Teacher(19,'女');
3、直接繼承prototype
function Person(){}
person.prototype.name = "xiaoming";

function Teacher(age,sex){
    this.age = age;
    this.sex = sex;
}

//Teacher的prototype對象直接指向Person的prototype對象
Teacher.prototype = Person.prototype;
Teacher.prototype.constructor = Teacher
var teacher1 = new Teacher(19,"女");
4、中介new function(){}空對象
var Fn = new function(){};
Fn.prototype = Person.prototype;
Teacher.prototype = new Fn();
Teacher.prototype.constructor = Teacher;

//擴展封裝
function Extend(ChildObj,ParentObj){
    var Fn = new function(){};
    Fn.prototype = ParentObj.prototype;
    ChildObj.prototype = new Fn();
    ChildObj.prototype.constructor = ChildObj;
    ChildObj.uber = ParentObj.prototype;  //直接指向父對象prototype屬性
}

//Teacher繼承Person
Extend(Teacher,Person);
var teacher1 = new Teacher(19,'女');
5、拷貝繼承(完全)
function Extend(ChildObj, ParentObj) {
    var p = ParentObj.prototype;
    var c = ChildObj.prototype;
    for (var i in p) { 
        c[i] = p[i];
  }
  c.uber = p;
} 
//Teacher繼承Person
Extend(Teacher,Person);
var teacher1 = new Teacher(19,'女');

非構造函數“繼承”(3種)

//原始
var Person = {
    name: '小明'
}
var Teacher ={
    age:19,
    sex:'女'
}

這裡我們如何可以讓Teacher繼承Person

1、object方法
function object(obj){
    function Fn(){}
    Fn.prototype = obj;
    return new Fn();
}
var teacher1 = object(Person);
teacher1.age = 19;
teacher1.sex = '女';
2、淺拷貝方法
function extendCopy(ParentObj){
    var c = {};
    for(var i in ParentObj){
        c[i] = p[i];
    }
    c.uber = p;
    return c;
}
//使用extendCopy
var teacher1 =  extendCopy(Person);
teacher1.age = 19;
teacher1.sex = '女';
3、深拷貝方法
function extendDeepCopy(ParentObj,ChildObj){
    var ChildObj = ChildObj || {};
    for(var i in ParentObj){
        if(typeof  ParentObj[i] === 'object'){
            c[i] = (ParentObj[i].constructor === Array) ? [] : {};
            extendDeepCopy(ChildObj[i],ParentObj[i]);
        }else{
            ChildObj[i] = ParentObj[i];
        }
    }
    return ChildObj;
}

//使用
var teacher1 = extendDeepCopy(Person1);
teacher1.age = 19;
teacher1.sex = '女';

本文版權歸作者共有,歡迎轉載,須保留此段聲明,並給出原文鏈接,謝謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 希望大家積極反饋,有不足和更好的方法請大家一起分享和研究,第一次寫博客,有描述不清楚的地方,希望大家給我私信,我會努力改正。 ...
  • 本文首發於 "博客園" ,併在 "GitHub" 上持續更新 前端的系列文章 。歡迎在GitHub上關註我,一起入門和進階前端。 以下是正文。 if語句 最基本的if語句 if語句的結構體:(格式) if語句也成為“選擇語句”、“條件判斷語句”。 多分支的if語句 格式: 以上所有的語句體中,只執行 ...
  • 直接上代碼! <!DOCTYPE html><html lang="en"><head> <title>小三角</title> <style> .up-triangle{ width:0px; height:0px; border-bottom:30px solid #000; border-lef ...
  • 在進行網站網頁設計製作的時候,經常需要用到不同的顏色的搭配,效果,網頁中標明顏色比較好的是用十六進位數據來進行標註,但是由於顏色很多,這些十六進位代碼數量龐大,所以blueslu整理了一些網站建設項目中網頁調色常用的顏色代碼,以備使用。 #9f0101 #67b55b #fff68f #ffd700 ...
  • Angular-搜索框及價格上下限 閑來無事,寫一個簡單的angular的搜索框。 1.要求: 利用 AngularJS 框架實現手機產品搜索功能,題目要求: 1)自行查找素材,按照原有數據格式將手機產品數據豐富到至少10個以上 2)自行設計頁面,需要包含“搜索條件部分”,“手機信息顯示部分” 3) ...
  • 先看background和background-color background:可以設置背景顏色,背景圖片,還有定位。預設background:no-repeat; background-color:只可以設置背景顏色。預設background:repeat; 設置透明度的方式有兩種: 第一種: ...
  • 這篇教程是由以太坊Mist瀏覽器的負責人撰寫,完整地介紹瞭如何開發一個標準的DApp。 ...
  • 新手跳坑。你寫的路徑路由是正確的,但是發現點擊了,一點反應也沒有,很可能是下下麵幾種原因: 1:你要跳轉的是tabBar中的頁面,需要用到專屬的跳轉方法switchtab 2:在app.js中沒有配置該頁面 3:頁面層級是不是超過五層了。可以用銷毀的跳轉方式 wx.navigateTo(OBJECT ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...