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