JavaScript 通過構(gòu)造函數(shù)生成新對象,因此構(gòu)造函數(shù)可以視為對象的模板。實例對象的屬性和方法,可以定義在構(gòu)造函數(shù)內(nèi)部。
通過構(gòu)造函數(shù)為實例對象定義屬性,雖然很方便,但是有一個缺點。同一個構(gòu)造函數(shù)的多個實例之間,無法共享屬性,從而造成對系統(tǒng)資源的浪費。
JavaScript 繼承機制的設(shè)計思想就是,原型對象的所有屬性和方法,都能被實例對象共享。也就是說,如果屬性和方法定義在原型上,那么所有實例對象就能共享,不僅節(jié)省了內(nèi)存,還體現(xiàn)了實例對象之間的聯(lián)系。
JavaScript 規(guī)定,每個函數(shù)都有一個prototype屬性,指向一個對象。這個對象就是函數(shù)的原型。
原型鏈:
JavaScript 規(guī)定,所有對象都有自己的原型對象(prototype)。一方面,任何一個對象,都可以充當其他對象的原型;另一方面,由于原型對象也是對象,所以它也有自己的原型。因此,就會形成一個“原型鏈”(prototype chain):對象到原型,再到原型的原型……
如果一層層地上溯,所有對象的原型最終都可以上溯到Object.prototype,即Object構(gòu)造函數(shù)的prototype屬性。也就是說,所有對象都繼承了Object.prototype的屬性。這就是所有對象都有valueOf和toString方法的原因,因為這是從Object.prototype繼承的。
那么,Object.prototype對象有沒有它的原型呢?回答是Object.prototype的原型是null。null沒有任何屬性和方法,也沒有自己的原型。因此,原型鏈的盡頭就是null。
constructor
prototype對象有一個constructor屬性,默認指向prototype對象所在的構(gòu)造函數(shù)。
ES6面向?qū)ο螅?br>
class ----- 構(gòu)造函數(shù)
對象 ----- 實例對象
ES5面向?qū)ο笫悄M面向?qū)ο蟆?/p>
constructor: 類的構(gòu)造函數(shù),類在實例化的時候自動調(diào)用。參數(shù)自動傳遞。
class 的屬性名可以是變量,但是這個變量需要使用[]包裝起來,表示變量的解析。
eg:
<script>
let name = 'limao';
let skill = 'chougan';
let s = Symbol('s'); //獨一無二的值
let ss = Symbol('ss');
console.log(s);
console.log(ss);
const obj = {
name,
skill,
say(){
console.log('say');
},
[s]:s,
};
console.log(obj.name)
obj.say();
console.log(obj[s])
</script>
class的內(nèi)在本質(zhì)還是一個function。
eg:
<script>
const a = Symbol();//常量
class Person{
constructor(name,skill){ //構(gòu)造函數(shù) ,new的時候自動的調(diào)用的,用于初始化的。自動傳遞參數(shù)
this.name = name;
this.skill = skill;
} // 不能有逗號
showName(){
console.log(`我的名字:${this.name}`);
}
showSkill(){
console.log(`我的技能:就是${this.skill}`);
}
[a](){
console.log(`我是Symbol數(shù)據(jù)類型的函數(shù)名`);
}
}
console.log(typeof Person);
let p1 = new Person('maqian','pang');
p1.showName();
p1.showSkill();
p1[a]();
</script>
對于ES5的構(gòu)造函數(shù)來說,本質(zhì)上定義的是一個函數(shù),函數(shù)和變量一樣,具有提升的特性,所以可以在構(gòu)造函數(shù)的申明之前進行實例化。
class沒有提升,所以在創(chuàng)建類對象的時候一定要保證類是先加載的。
etter與getter:
封裝class內(nèi)部成員屬性的作用。
語法。
自動能調(diào)用。
set 語法定義的函數(shù),外部在調(diào)用函數(shù)名為屬性的屬性設(shè)置值的時候調(diào)用。
get 語法定義的函數(shù)。外部在獲取這個函數(shù)名為屬性的屬性的時候調(diào)用。
有的時候我們需要不創(chuàng)建對象,直接使用類去執(zhí)行某些事情,這個時候就可以設(shè)計靜態(tài)方法。
static 靜態(tài)的。不需要實例化對象去調(diào)用的方法。
靜態(tài)方法里面的this指類本身。而不是對象。
靜態(tài)方法直接使用類名調(diào)用,不能使用對象調(diào)用。
靜態(tài)的類: Math
var proxy = new Proxy(target, handler);
target : 要進行代理的對象。
handler:代理的規(guī)則。
代理:幫助做一些事情。
property:屬性
method:方法
const:定義一個常量(與let相比它的速度比較快)
字符串模板:
1.' ';
2." ";
3.`${}`;
object.assign()
用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象,將它返回目標對象
語法:object.assign(target,...sources)
target:目標對象
sources:源對象
extends
關(guān)鍵字用于類聲明或者類表達式中,以創(chuàng)建一個類,該類是另一個的子類
語法:class childclass exends Parentclass{...}
關(guān)鍵字用來創(chuàng)建一個普通類或者內(nèi)建對象的子類
繼承的 .prototype 必須是一個object或者null
apply()與call()
調(diào)用一個對象的一個方法,用另一個對象替換當前對象
eg:
B.apply(A,arguments);//即A對象應用B對象的方法
B.call(A,args1,args2);//即A對象調(diào)用B對象的方法
不同之處:
apply:最多只能有兩個參數(shù),新this對象和一個數(shù)組argArray,如果給該方法傳遞多個參數(shù),則把參數(shù)都寫進這個數(shù)組里面,即使只有一個參數(shù),也要寫進數(shù)組里
call:它可接受多個參數(shù),第一個參數(shù)與apply一樣,后面則是一串參數(shù)列表。主要用在js對象各方法相互調(diào)用的時候
Symbol
Es6引入了一種新原始數(shù)據(jù)類型symbol,表示獨一無二的值;
symbol函數(shù)前不能使用new命令,否則會報錯,這是因為生成的symbol是一個原始類型的值,不是對象symbol函數(shù)可以接受一個字符串作為參數(shù),表示對symbol實例的描述,主要是為了在控制顯示,或者轉(zhuǎn)為字符串時,比較容易區(qū)分。