對象

1. 對象的創(chuàng)建

  • 對象直接量
    -- 舉例:
var empty = {};
var point = {x:0, y:0};
var point = {x: point.x, y: point.y}
var book = {
  "main title": "Javascript",
  'sub-title': "The Definitive Guide",
  author:{
    firstname: "David"亏吝,
    surname:"Flanagan"
  }
}
  • 通過new創(chuàng)建對象
    --舉例:(除了下面的這些內(nèi)置的構(gòu)造函數(shù)核偿,還可以通過自定義的構(gòu)造函數(shù)來初始化新對象)
var z = new Object();
var a = new Array(); // 效果同[]
var d = new Date();
var r = new RegExp("js");
new 的過程是什么脐彩,發(fā)生了什么彬碱?
分析: 
1.創(chuàng)建一個空對象  
2.將空對象的原型指向new 后面的構(gòu)造函數(shù)的原型
3.改變構(gòu)造函數(shù)的this指向新的對象
4.返回這個新的對象
function create(){
  // 刪除arguments的第一項(xiàng)生年,con等于刪除的那項(xiàng)蠢终,也就是constructor
  let con =[].prototype.shift.call(arguments);
  // 創(chuàng)建一個空的對象讳癌,并且可以訪問到構(gòu)造函數(shù)的原型
  let newObj=Object.create(con.prototype);
  // 綁定this, con的this現(xiàn)在指向newObj
  let res = con.apply(newObj, arguments);
  // 優(yōu)先返回構(gòu)造函數(shù)返回的對象
  return res instanceof Object ? res : newObj;
}
  • Object.create()
    -- 首先了解一下原型的概念:每一個js對象(除null外)都和另外一個對象相關(guān)聯(lián)穿稳,這個另外一個對象就是我們說的原型,每一個對象都從原型繼承屬性

      1. 所有通過對象直接量創(chuàng)建的對象都具有同一個原型對象晌坤,并可以通過js代
        碼Object.prototype獲得對原型對象的引用逢艘。
      1. 通過new和構(gòu)造函數(shù)調(diào)用創(chuàng)建的對象的原型就是構(gòu)造函數(shù)的prototype屬性
        值,因此通過new Object()創(chuàng)建的對象也繼承自O(shè)bject.prototype骤菠。
      1. new Array()創(chuàng)建的對象的原型是Array.prototype它改。
      1. new Date()創(chuàng)建的對象的原型是Date.prototype。

    -- Object.create(第一個參數(shù)(對象的原型)商乎,第二個參數(shù)央拖?(用以對對象的屬性進(jìn)行進(jìn)一步描述))

var o1 = Object.create({x:1, y:2}); // o1繼承了屬性x和y
// 通過傳入?yún)?shù)null,來創(chuàng)建一個沒有原型的對象
var o2 = Object.create(null); //o2不繼承任何屬性和方法
console.log(o2); // {}  No properties
// 通過傳入?yún)?shù)Object.prototype可以創(chuàng)建一個普通的空對象
var o3 = Object.create(Object.prototype); // o3和{} 和new Object()一樣
console.log(o3); // {}

/**通過原型繼承創(chuàng)建一個新對象
1.inherit()返回了一個繼承自原型p的屬性的新對象
*/
function inherit(p) {
// 首先判斷p是否為null或者undefined,因?yàn)閜是一個對象
  if (p == null || p == undefined) throw TypeError();
//如果Object.create()存在直接使用它創(chuàng)建對象
  if (Object.create) {
    return Object.create(p);
  }
// 如果不存在,先判斷p是否是一個對象或者函數(shù)鹉戚,不是則報(bào)錯
  var typeObject = typeof(p);
  if (typeObject !== 'object' && typeObject !== 'function') throw TypeError();
  function f(){}; // 定義一個空的構(gòu)造函數(shù)
  f.prototype = p; // 將原型屬性設(shè)置為p
  return new f(); // 使用f()創(chuàng)建p的繼承對象
}

2.繼承

  • 通過【某種方式】讓一個對象可以訪問到另一個對象中的屬性和方法鲜戒,我們把這種方式稱之為繼承。

1)原型鏈繼承:

//實(shí)現(xiàn):重寫原型對象抹凳,使用一個新類型實(shí)例替換
//核心代碼:
//SuperType的所有屬性和方法都會在subType的原型中查詢到
subType.prototype = new SuperType();
//缺點(diǎn):多個實(shí)例對引用類型操作會被篡改

2)借用構(gòu)造函數(shù)實(shí)現(xiàn)繼承

//實(shí)現(xiàn):使用父類的構(gòu)造函數(shù)來增強(qiáng)子類實(shí)例,等同于復(fù)制父類的實(shí)例給子類(不使用原型)
//核心代碼:
//SuperType的所有屬性和方法都會被復(fù)制,并且在subType類中直接查詢到
SuperType.call(this)
創(chuàng)建子類實(shí)例時調(diào)用SuperType構(gòu)造函數(shù)泄伪,于是SubType的每個實(shí)例都會將SuperType的屬性復(fù)制一份
// 缺點(diǎn):
//只能繼承父類的實(shí)例屬性和方法,不能繼承原型屬性/方法
//無法實(shí)現(xiàn)復(fù)用柏蘑,每個子類都有父類實(shí)例函數(shù)的副本,影響性能

3)組合繼承

function SubType(){
  SuperType.call(this);
}
SubType.prototype=new SuperType()粹庞;
console.log(SubType.prototype.constructor===SuperType);//true
//關(guān)于為什么要修復(fù)構(gòu)造函數(shù)的指向可以查閱資料:https://blog.csdn.net/Jane617_min/article/details/79744986
//如果不加下面這句代碼的話咳焚,subType這個類的constructor指向的就是SuperType
SubType.prototype.constructor = SubType;
//缺點(diǎn):
//在使用子類創(chuàng)建實(shí)例對象時,其原型中會存在兩份相同的屬性/方法信粮。

4)原型式繼承

var SubType = object.create(SuperType);
//直接進(jìn)行一個淺復(fù)制黔攒,將構(gòu)造函數(shù)SubType的原型直接指向SuperType
//缺點(diǎn):
//沒有辦法傳遞參數(shù)
//存在數(shù)據(jù)篡改的可能,因?yàn)檫@個屬于淺復(fù)制

5)寄生式繼承

//作用:為構(gòu)造函數(shù)新增屬性和方法强缘,以增強(qiáng)函數(shù)
//基于原型式繼承督惰,增強(qiáng)對象,返回構(gòu)造函數(shù)
function createAnother(SuperType){
  var clone = object.create(SuperType);
  clone.sayHi=function(){
    alter("hi");
  }
  return clone;
}
//缺點(diǎn):
//(同原型式繼承)
//1.多個實(shí)例的引用類型屬性指向相同旅掂,存在篡改的可能赏胚;
//2.無法傳遞參數(shù)

6)寄生式組合繼承(最成熟也是現(xiàn)在庫實(shí)現(xiàn)的方法)

//首先借用構(gòu)造函數(shù)傳遞增強(qiáng)子類實(shí)例屬性(支持傳參和避免篡改)
function SubType(name, age){
  SuperType.call(this, name);
  this.age=age;
}
// 寄生模式
function inheritPrototype(subType, superType){
  var prototype = Object.create(superType.prototype);//重寫原型失去了默認(rèn)的constructor
  prototype.constructor=subType;//彌補(bǔ)上一步操作造成的constrictor缺失
  subType.prototype = prototype;//將新創(chuàng)建的對象賦值給子類的原型
}

7)混入方式繼承多個對象

// 重點(diǎn):使用Object.assign(target, source):只會拷貝源對象自身的并且可枚舉的屬性到目標(biāo)對象
function MyClass(){
  SuperClass.call(this);
  OtherSuperClass.call(this);
}
MyClass.prototype = Object.create(SuperClass.prototype);
Object.assign(MyClass.prototype,OtherSuperClass.prototype);
MyClass.prototype.constructor=MyClass;

8)es6類繼承extends

// extends關(guān)鍵字主要用于類聲明或者類表達(dá)式中,以創(chuàng)建一個類商虐,該類是另一個類的子類
class Rectangle{
  constructor(height, width){
    this.height = height;
    this.width = width;
  }
}
//繼承
class Square extends Rectangle{
  constructor(length){
  //super在這里表示父類的構(gòu)造函數(shù)觉阅,用來新建一個父類的實(shí)例對象。
  //子類構(gòu)造函數(shù)調(diào)用super()時秘车,會執(zhí)行一次父類構(gòu)造函數(shù)典勇。
  //在子類的構(gòu)造函數(shù)中,只有調(diào)用super()之后叮趴,才可以使用this關(guān)鍵字割笙,否則會報(bào)錯
    super(length, length);
  }
}

es5和es6在繼承上的區(qū)別:

  1. es5是:先創(chuàng)造一個獨(dú)立的子類的實(shí)例對象,再將父類的方法和屬性添加到子類對象上眯亦,屬于“實(shí)例在前伤溉,繼承在后”;
  2. es6是:先將父類的屬性和方法加到一個空的對象上妻率,然后再將該類作為子類的實(shí)例對象乱顾,屬于“繼承在前,實(shí)例在后”
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宫静,一起剝皮案震驚了整個濱河市走净,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孤里,老刑警劉巖温技,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扭粱,居然都是意外死亡舵鳞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門琢蛤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜓堕,“玉大人抛虏,你說我怎么就攤上這事√撞牛” “怎么了迂猴?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長背伴。 經(jīng)常有香客問我沸毁,道長,這世上最難降的妖魔是什么傻寂? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任息尺,我火速辦了婚禮,結(jié)果婚禮上疾掰,老公的妹妹穿的比我還像新娘搂誉。我一直安慰自己,他們只是感情好静檬,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布炭懊。 她就那樣靜靜地躺著,像睡著了一般拂檩。 火紅的嫁衣襯著肌膚如雪侮腹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天稻励,我揣著相機(jī)與錄音父阻,去河邊找鬼。 笑死钉迷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钠署。 我是一名探鬼主播糠聪,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谐鼎!你這毒婦竟也來了舰蟆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤狸棍,失蹤者是張志新(化名)和其女友劉穎身害,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體草戈,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡塌鸯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唐片。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丙猬。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡涨颜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茧球,到底是詐尸還是另有隱情庭瑰,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布抢埋,位于F島的核電站弹灭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏揪垄。R本人自食惡果不足惜穷吮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望福侈。 院中可真熱鬧酒来,春花似錦、人聲如沸肪凛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伟墙。三九已至翘鸭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間戳葵,已是汗流浹背就乓。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拱烁,地道東北人生蚁。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像戏自,于是被迫代替她去往敵國和親邦投。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容