摘要:即另外,注意到構(gòu)造函數(shù)里的屬性,都沒有經(jīng)過進(jìn)行初始化,而是直接使用進(jìn)行綁定。并且在模式下,構(gòu)造函數(shù)沒有使用進(jìn)行調(diào)用,也會(huì)導(dǎo)致報(bào)錯(cuò)。調(diào)用構(gòu)造函數(shù)千萬(wàn)不要忘記寫。
1. 基礎(chǔ)
JavaScript不區(qū)分類和實(shí)例的概念,而是通過原型來實(shí)現(xiàn)面向?qū)ο缶幊獭?br>Java是從高級(jí)的抽象上設(shè)計(jì)的類和實(shí)例,而JavaScript的設(shè)計(jì)理念,聽起來就好比Heros里的Peter,可以復(fù)制別人的能力。JavaScript就是別人的所有屬性都拷貝過來,成為自己的一部分,并能夠保留自身的能力。
看廖老師的圖片,應(yīng)該就能感覺出咋回事了,xiaoming這個(gè)實(shí)例把自己的__proto__指向Student就實(shí)現(xiàn)了繼承,這種繼承關(guān)系是脆弱的,也是動(dòng)態(tài)可以修改的。
但是JavaScript是不推薦直接使用__proto__進(jìn)行繼承的。提供了一個(gè)Object.creat(原型)來創(chuàng)建對(duì)象。這是JavaScript的一種原型繼承的方法,如下實(shí)例。
var Student = { name : "robot", height:180, run:function(){ console.log(this.name + " is running"); }, grade:()=>"4"+"grade" }; function createStudent(name){ var s = Object.create(Student); // init new object s.name = name; return s; }; var xiaoming = createStudent("xiaosfsffsfsf");2. 創(chuàng)建對(duì)象
當(dāng)我們用obj.xxx訪問一個(gè)對(duì)象的屬性時(shí),JavaScript引擎先在當(dāng)前對(duì)象上查找該屬性,如果沒有找到,就到其原型對(duì)象上找,如果還沒有找到,就一直上溯到Object.prototype對(duì)象,最后,如果還沒有找到,就只能返回undefined。
以上說明JavaScript引擎有個(gè)追朔系統(tǒng),優(yōu)先使用當(dāng)前域的進(jìn)行查找,不行則向上一個(gè)原型內(nèi)進(jìn)行查找。
除了使用{...}進(jìn)行創(chuàng)建對(duì)象,還可以使用new 的方法,需要先定義一個(gè)構(gòu)造函數(shù),如下所示。如果使用new那么這個(gè)函數(shù)就會(huì)默認(rèn)返回this這個(gè)對(duì)象,如果不是用new,直接調(diào)用,那么這個(gè)函數(shù)就返回undefined,像普通的函數(shù)一樣。
function Student(name){ this.name = name; this.hello = function(){ alert("hello"+name); } } var stu = new Student("XiaoMing");
新創(chuàng)建的stu的原型鏈?zhǔn)?/p>
stu ----> Student.prototype ----> Object.prototype ----> null
用new Student創(chuàng)建的對(duì)象stu,還從Student上繼承了constructor屬性,它指向Student本身。
stu.constructor === Student.prototype.constructor; // true Student.prototype.constructor === Student; // true Object.getPrototypeOf(stu) === Student.prototype; // true stu instanceof Student; // true
這個(gè)原型鏈還是盜用liaoxuefeng老師的圖
可以看出實(shí)際上Student,xiaoming,xiaohong的原型都是指向Student.prototype。當(dāng)前每個(gè)對(duì)象的hello方法都是不同的,屬于不同的對(duì)象。但根據(jù)方法查找規(guī)則,如果把hello放在Student.prototype上,就可以實(shí)現(xiàn)共用同一個(gè)方法,節(jié)省內(nèi)存。即:
function Student(name) { this.name = name; } Student.prototype.hello = function () { alert("Hello, " + this.name + "!"); };
另外,注意到構(gòu)造函數(shù)里的屬性,都沒有經(jīng)過var進(jìn)行初始化,而是直接使用this.xxx進(jìn)行綁定。所以如果沒用new,而是直接調(diào)用構(gòu)造函數(shù),那么將會(huì)使this指向window,然后內(nèi)部的各個(gè)屬性都將添加到window上,無意中添加全局變量。并且在strict模式下,構(gòu)造函數(shù)沒有使用new進(jìn)行調(diào)用,也會(huì)導(dǎo)致報(bào)錯(cuò)。
***調(diào)用構(gòu)造函數(shù)千萬(wàn)不要忘記寫new。為了區(qū)分普通函數(shù)和構(gòu)造函數(shù),按照約定,構(gòu)造函數(shù)首字母應(yīng)當(dāng)大寫,而普通函數(shù)首字母應(yīng)當(dāng)小寫,這樣,一些語(yǔ)法檢查工具如jslint將可以幫你檢測(cè)到漏寫的new。***
練習(xí)
function Cat(name) { this.name = name; } Cat.prototype.say = function(){ return "Hello, "+this.name+"!"; }
在此基礎(chǔ)上,我們還可以創(chuàng)建一個(gè)createCat()函數(shù),在內(nèi)部封裝所有的new 操作。
function Cat(props) { this.name = props.name || "波斯貓"; this.color = props.name || "黑白"; } Cat.prototype.say = function(){ return "Hello, I am " + this.color + this.name+"!"; } function createCat(props){ return new Cat(props || {}); }
這樣就不需要new 操作了,參數(shù)也很靈活,可以不傳入,也可以傳少量的,其他的屬性將會(huì)由默認(rèn)的值替代。而且參數(shù)不需要考慮順序,可對(duì)收到的JSON直接生成對(duì)象。
3. 原型繼承JavaScript的原型繼承實(shí)現(xiàn)方式就是:
定義新的構(gòu)造函數(shù),并在內(nèi)部用call()調(diào)用希望“繼承”的構(gòu)造函數(shù),并綁定this;
借助中間函數(shù)F實(shí)現(xiàn)原型鏈繼承,最好通過封裝的inherits函數(shù)完成;
繼續(xù)在新的構(gòu)造函數(shù)的原型上定義新方法。
廖老師的一張圖簡(jiǎn)單扼要說明這個(gè)繼承模型。
其實(shí)3是不太重要的,因?yàn)镋S6已經(jīng)推出了class這個(gè)關(guān)鍵字來解決繁瑣的原型鏈繼承的復(fù)雜性,就像java一樣好,但底層其實(shí)還是原型鏈繼承實(shí)現(xiàn),這一點(diǎn)并沒有變化。
class Cat extends Animal{
constructor(name){ super(name); } say(){ return "Hello, "+this.name+"!"; }
}
say()方法,實(shí)例依然是共享的。but,這個(gè)需要較新的瀏覽器支持,一般還用不了,但是可以使用Babel這個(gè)庫(kù)去兼容這個(gè)玩意,其實(shí)我不了解這是個(gè)啥庫(kù)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86496.html
摘要:網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知識(shí)點(diǎn)羅列為主或是資料的匯總,數(shù)據(jù)量讓新人望而卻步。天了解一個(gè)前端框架。也可以關(guān)注微信公眾號(hào)曉舟報(bào)告,發(fā)送獲取資料,就能收到下載密碼,網(wǎng)盤地址在最下方,獲取教程和案例的資料。 前言 好的學(xué)習(xí)方法可以事半功倍,好的學(xué)習(xí)路徑可以指明前進(jìn)方向。這篇文章不僅要寫學(xué)習(xí)路徑,還要寫學(xué)習(xí)方法,還要發(fā)資料,干貨滿滿,準(zhǔn)備接招。 網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知...
摘要:示例代碼如下索引數(shù)組輸出結(jié)果為索引數(shù)組關(guān)聯(lián)數(shù)組注意關(guān)聯(lián)數(shù)組的數(shù)組的長(zhǎng)度與元素的個(gè)數(shù)不一致,原因是的官方不支持關(guān)聯(lián)數(shù)組。定義一個(gè)空數(shù)組訪問二維數(shù)組中的元素循環(huán)遍歷二維數(shù)組 數(shù)組 概述 數(shù)組是什么 數(shù)組是值的有序集合。數(shù)組中的每個(gè)值叫做一個(gè)元素,而每個(gè)元素在數(shù)組中都右一個(gè)唯一的位置。這個(gè)位置用數(shù)字表示,叫做索引數(shù)組;用字符串表示,叫做關(guān)聯(lián)數(shù)組。JavaScript數(shù)組是無類型的;數(shù)組的元素...
摘要:在近期看到了函數(shù)式編程這本書預(yù)售的時(shí)候就定了下來。主要目的是個(gè)人目前還是不理解什么是函數(shù)式編程。且和現(xiàn)在在學(xué)習(xí)函數(shù)式編程有莫大的關(guān)系。加速大概了解了函數(shù)式編程之后。總結(jié)看完了第一章也是可以小結(jié)一下的函數(shù)式編程。 本文章記錄本人在學(xué)習(xí) 函數(shù)式 中理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復(fù)習(xí)。 在近期看到了《JavaScript函數(shù)式編程》這本書預(yù)售的時(shí)候就定了下...
摘要:我們一般不判斷是,判斷不是在判斷元素是否存在時(shí)候,最好使用如果沒有定義會(huì)有警告第三章,函數(shù)返回值一個(gè)函數(shù)只能有一個(gè)返回值,如果有多個(gè)返回值,使用數(shù)組的形式返回。子句,返回值,就是函數(shù)的返回值。示例將一個(gè)函數(shù)的返回值傳遞給另一個(gè)函數(shù)。 第一章 1,用自己的語(yǔ)言描述出,什么是對(duì)象、類、封裝、聚合、繼承、多態(tài)? 對(duì)象,擁有屬性和方法的任何抽象概念。 類,可以實(shí)例化,有共同屬性或方法(行為)的...
摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來。注意中,對(duì)象一定是通過類的實(shí)例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
閱讀 1683·2023-04-26 00:30
閱讀 3155·2021-11-25 09:43
閱讀 2884·2021-11-22 14:56
閱讀 3194·2021-11-04 16:15
閱讀 1155·2021-09-07 09:58
閱讀 2028·2019-08-29 13:14
閱讀 3113·2019-08-29 12:55
閱讀 993·2019-08-29 10:57