欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

JS面向?qū)ο缶幊獭狤S6中class的繼承用法詳解

本文實(shí)例講述了 ES6 中class的繼承用法。分享給大家供大家參考,具體如下:

創(chuàng)新互聯(lián)專注于濮陽(yáng)縣企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。濮陽(yáng)縣網(wǎng)站建設(shè)公司,為濮陽(yáng)縣等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

JS是一種基于對(duì)象的語(yǔ)言,要實(shí)現(xiàn)面向?qū)ο?,寫法跟傳統(tǒng)的面向?qū)ο笥泻艽蟮牟町?。ES6引入了Class語(yǔ)法糖,使得JS的繼承更像面向?qū)ο笳Z(yǔ)言的寫法。

此篇博客,分為:基本介紹、Vue使用案例

基本介紹

Class可以通過extends關(guān)鍵字實(shí)現(xiàn)繼承,這比ES5的通過修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多;

class Father {
 }
class Son extends Father {
}

代碼定義了一個(gè)Son 類,該類通過extends關(guān)鍵字,繼承了Father類的所有屬性和方法,但是由于沒有部署任何代碼,所以這兩個(gè)類完全一樣,等于復(fù)制了一個(gè)Father類。

class Son extends Father {
     constructor (name,age,city) {
        super(name,age);//調(diào)用父類的constructor(name,age);
        this.city = city;
      }
 
      toString () { 
         return this.city+ " " +super.toString();//調(diào)用父類的toString()
      }
}

constructor方法和toString方法之中,都出現(xiàn)了super關(guān)鍵字,他在這里表示父類的構(gòu)造函數(shù),用來(lái)新建父類的this對(duì)象;

子類必須在constructor方法中調(diào)用super方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò),這是因?yàn)樽宇悰]有自己的this對(duì)象,而是繼承父類的this對(duì)象,然后對(duì)其進(jìn)行加工,如果不調(diào)用super方法,子類就得不到this對(duì)象;

class Father {  }
 
class Son extends Father {
     constructor(){ }
}
let s = new Son();
//referenceError : this is not defined 

Son繼承了父類Fatherm,但是他的構(gòu)造函數(shù)沒有調(diào)用super方法,這導(dǎo)致新建實(shí)例時(shí)報(bào)錯(cuò);
ES5的繼承,實(shí)質(zhì)是先創(chuàng)造子類的實(shí)例對(duì)象this,然后再將父類的方法添加到this上(Parent.apply(this)),ES6的繼承機(jī)制完全不同,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象this(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this;
如果子類沒有定義constructor方法,這個(gè)方法會(huì)默認(rèn)添加,也就是說(shuō),不管有沒有顯式定義,任何一個(gè)子類都有constructor方法。

class Son extends Father {
}
 
//等同于
class Son extends Parent {
    constructor(...args) {
    super(...args);
   }
}

另一個(gè)需要注意的是:在子類的構(gòu)造函數(shù)中,只有調(diào)用super之后,才能使用this關(guān)鍵字,否則會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇悓?shí)例的構(gòu)建,是基于對(duì)父類實(shí)例加工,只有super方法才能返回父類實(shí)例;

class Father {
   constructor (x,y) {
      this.x= x;
      this.y = y;
    }
}
 
class Son extends Father {
   constructor (x, y, color) {
       this.color =color ;//ReferenceError : this is not defined
      super(x,y);
       this.color = color;//正確
      }
}
 
let s = new Son(25,8,"green");
s instanceof Son //true 
s instanceof Father //true

子類的constructor方法沒有調(diào)用super之前,就使用this關(guān)鍵字,結(jié)果報(bào)錯(cuò),而放在super方法之后就是正確的;

Object.getPrototypeOf()方法用來(lái)從子類上獲取父類

Object.getPrototypeOf( Son ) ===Father
//true
//因此可以用這個(gè)方法判斷,一個(gè)類是否繼承了另一類

super 關(guān)鍵字
super這個(gè)關(guān)鍵字,既可以當(dāng)作函數(shù)使用,也可以當(dāng)作對(duì)象使用,
(1)第一情況是:super當(dāng)作函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù),ES6要求,子類的構(gòu)造函數(shù)必須執(zhí)行一個(gè)super函數(shù);

class Father { }
 
class Son extends Father {
    constructor () {
          super();
       }
}
//子類Son的構(gòu)造函數(shù)之中的super(),代表調(diào)用父類的構(gòu)造函數(shù)。這是必須的,否則 JavaScript 引擎會(huì)報(bào)錯(cuò)。

super雖然代表了父類Father的構(gòu)造函數(shù),但是返回的是子類Son的實(shí)例,即super內(nèi)部的this指向的是Son,因此super()在這里相當(dāng)于Father.constructor.call(this);
而且作為函數(shù)時(shí),super()只能用在子類的構(gòu)造函數(shù)中,在其他地方會(huì)報(bào)錯(cuò);

class A {
     constructor (){
        console.log(new.target.name);
      }
 }
 
class B extends A {
   constructor () {
      super();
      }
 }
  new A()//A
 new B()//B 

new.target指向當(dāng)前正在執(zhí)行的函數(shù),在super()執(zhí)行時(shí),他指向的是子類B的構(gòu)造函數(shù),而不是父類A的構(gòu)造函數(shù),super()內(nèi)部的this指向的是B;

(2)第二種情況,super作為對(duì)象時(shí),在普通方法中,指向父類的原型對(duì)象,在靜態(tài)方法中,指向父類;

class Father{
   getName ( ) {
     return "MGT360124";
   }
}
class Son extends Father {
    constructor () {
    super();
    console.log(super.getName() ) //“MGT360124”
    }
}
let s = new Son();

子類Son中的super.p()就是將super當(dāng)作一個(gè)對(duì)象使用,這時(shí),super在普通方法中,指向Father.prototype,所以super.getName()就相當(dāng)于Father.prototype.getName();//"MGT360124",由于super指向父類的原型對(duì)象,所以定義在父類實(shí)例上的方法或者屬性,是無(wú)法通過super調(diào)用的;

class Father {
   constructor () {
       this.p =2
     }
}
 
class Son extends Father {
     get m ( ) {
          return super.p;
     }
     getValue ( ) {
          return super.a;
      }
}
let s = new Son();
s.m
//undefined

p是父類Father實(shí)例的屬性,super.p就引用不到它

如果屬性定義在父類的原型對(duì)象上,super就可以取到。

class A {}
A.prototype.x = 2;
 
class B extends A {
 constructor() {
  super();
  console.log(super.x) // 2
 }
}
 
let b = new B();

屬性x是定義在A.prototype上面的,所以super.x可以取到它的值。

ES6 規(guī)定,通過super調(diào)用父類的方法時(shí),super會(huì)綁定子類的this。

class Father {
   constructor () {
      this.x =1;//這個(gè)this指向的是Father對(duì)象的實(shí)例
   }
   print () {
      console.log(this.x);
   }
}
 
class Son extends Father {
   constructor () {
       super();
        this.x = 2;//這個(gè)this指向的是Son對(duì)象的實(shí)例
   }
     m() {
      super.print();    
     }
}
let s = new Son();
s.m();
//2 

super.print()雖然調(diào)用的是Father.prototype.print(),但是Father.prototype.print()會(huì)綁定子類Son的this,導(dǎo)致輸出的是2,而不是1,也就是說(shuō),實(shí)際上執(zhí)行的是 super.print.call(this)。

如果super作為對(duì)象,用在靜態(tài)方法中,這時(shí)super將指向父類,而不是父類的原型對(duì)象;

class Parent {
      static myMethod (msg) {
           console.log("static",msg);
        }
      myMethod (msg) {
          console.log("instance" ,msg);
        }
}
 
class Child extends Parent {
     static myMethod(msg) {
        super.myMethod(msg);
     }
      myMethod (msg) {
      super.myMethod(msg);
      }
 }
 
Child.myMethod(1);
//static 1
var child = new Child();
child.myMethod(2);
//instance 2

super在靜態(tài)方法之中指向父類,在普通方法之中指向父類的原型對(duì)象。
注意,使用super的時(shí)候,必須顯式指定是作為函數(shù)、還是作為對(duì)象使用,否則會(huì)報(bào)錯(cuò)。
類的prototype屬性和proto屬性
大多數(shù)瀏覽器的ES5實(shí)現(xiàn)之中,每一個(gè)對(duì)象都有proto屬性,指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性,class作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有prototype屬性和proto屬性,因此同時(shí)存在兩條繼承鏈;
(1)子類的proto屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類;
(2)子類prototype屬性的proto屬性,表示方法的繼承,總是指向父類的prototype屬性;

class A{
}
class B{
}
//B的實(shí)例繼承A的實(shí)例
Object.setPrototypeOf(B.prototype, A.prototype);
 
//B 的實(shí)例繼承A的靜態(tài)屬性
Object.setPrototypeOf(B,A);
 
const b = new B();

《對(duì)象的擴(kuò)展》一章中Object.setPrototypeOf()方法的實(shí)現(xiàn):

Object.setPrototypeOf = function (obj, proto) {
obj.__proto__ = proto;
  return obj ;
}

因此

Object.setPrototypeOf( B.prototype , A.prototype );
//等同于
B.prototype.__proto__ = A.prototype ;
 
Object.setPrototypeOf(B, A);
//等同于
B.__proto__ = A;

這兩條繼承鏈,可以理解為:作為一個(gè)對(duì)象,子類B的原型(proto屬性)是父類(A);作為一個(gè)構(gòu)造函數(shù),子類B的原型對(duì)象(prototype屬性)是父類的原型對(duì)象(prototype)的實(shí)例;

extends的繼承目標(biāo)
extends關(guān)鍵字后面可以跟很多類型的值;

class B extends A{
}

只要A有一個(gè)prototype屬性的函數(shù),就能被B繼承,由于函數(shù)都有prototype屬性(除了Function.prototype函數(shù)),因此A可以使任意函數(shù),下面三種情況:
(1)子類繼承Object類

class A extends Object {
}
A.__proto__ === Object //true;
A.prototype.__proto__ === Object.prototype //true

這種情況就是 : A就是構(gòu)造函數(shù)Object的復(fù)制,A的實(shí)例就是Object的實(shí)例
(2)不存在任何繼承

class A {
}
A.__proto__ === Function.prototype //true
A.prototype.__proto__ = Object.prototype //true

這種情況是:A作為一個(gè)基類(不存在任何繼承),就是一個(gè)普通的函數(shù),所以直接繼承Function.prototype。但是A調(diào)用后返回一個(gè)空對(duì)象(即Object實(shí)例),所以A.prototype.proto指向構(gòu)造函數(shù)(Object)的prototype屬性;
實(shí)例的proto屬性
子類實(shí)例的proto屬性的proto屬性,指向父類實(shí)例的proto屬性。也就是說(shuō),子類的原型的原型,是父類的原型。

原生構(gòu)造函數(shù)的繼承
原生構(gòu)造函數(shù)是指語(yǔ)言內(nèi)置的構(gòu)造函數(shù),通常用來(lái)生成數(shù)據(jù)結(jié)構(gòu)。

Boolean()
Number()
String()
Array()
Date()
Function()
RegExp()
Error()
Object()

extends關(guān)鍵字不僅可以用來(lái)繼承類,還可以用來(lái)繼承原生的構(gòu)造函數(shù)。因此可以在原生數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)上,定義自己的數(shù)據(jù)結(jié)構(gòu)。

vue使用

testClass.js

//定義類
class Person{ 
	// 構(gòu)造 
	constructor(x,y){ 
		this.x = x; 
		this.y = y; 
	} 
 
  //定義在類中的方法不需要添加function
	toString(){ 
		return (this.x + "的年齡是" +this.y+"歲"); 
	} 
} 
export {
	Person
}; 

test.vue

<template>
	<div>
		<p id="testJs"></p>
	</div>
</template>
<script>
import {Person} from './testClass.js'; 
export default {  
	data() {
		return {
		}
	},
	mounted(){
		let text=document.getElementById("testJs");
		//使用new的方式得到一個(gè)實(shí)例對(duì)象
		let person = new Person('張三',12); 
		text.innerHTML=person.toString();//張三的年齡是12歲
		console.log(typeof Person);//function 
	}
}
</script>

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

新聞標(biāo)題:JS面向?qū)ο缶幊獭狤S6中class的繼承用法詳解
URL標(biāo)題:http://aaarwkj.com/article40/iggieo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)服務(wù)器托管、靜態(tài)網(wǎng)站、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
色久悠悠婷婷综合在线亚洲| 青青草成人公开在线视频| 久久九九精品日本人妻视频| 亚洲成在人线天堂网站| 日韩在线不卡av一区二区| 在线观看日韩精品电影| 欧美日韩亚洲高清专区| 久久精品久久精品欧美大片| 九九视频免费观看91| 中文字幕乱码亚州精品一区| 亚洲国产精品一区二区首页| 成人免费视频一区二区三区| 可以免费在线看的av网站| 欧美激情中文字幕日韩精品| 欧美熟妇精品一区二区蜜桃| 亚洲一区二区日韩在线| 中文有码人妻字幕在线| 日本午夜专区一区二区| 精品乱码一区二区三区四区| 欧美电影剧情av在线| 日韩人成理论午夜福利| 少妇午夜福利一区二区| 成年爽片在线观看播放欧美| 亚洲色图视频免费观看| 一区二区在线观看激情| 美女呻吟被爽到高潮在线| 亚洲人成网站18禁止人| 18岁下禁止看的视频| 久久这里只有精品视频| 中文字幕人妻在线播放| 日本少妇一区二区99| 亚洲免费av一区二区| 大香蕉一区二区亚洲欧美| 亚洲一区二区三区av电影| 爽妇网亚洲一区二区三区| 欧美高清在线观看一区二区| 成人精品播放视频在线观看| 精品在线免费视频观看| 天堂8在线最新版av| 青青草手机在线视频免费观看| 亚洲国产黄片在线播放|