原型 原型鏈 call/apply

原型

原型是function對(duì)象的一個(gè)屬性倦淀,它定義了構(gòu)造函數(shù)制造出的對(duì)象的祖先暂衡。通過(guò)該構(gòu)造函數(shù)構(gòu)造出來(lái)的對(duì)象朵耕,可以繼承該原型的屬性和方法似袁。原型也是對(duì)象

原型知識(shí)講解

舉一個(gè)小栗子

    Person.prototype.lastName="deng";
    function Person(name,sex){
        this.name=name;
        this.sex=sex;
    }
    var person = new Person("xiaoliu",'male');

prototype的講解

通過(guò)上面的代碼我們不難看出,對(duì)象可以訪問(wèn)到訪問(wèn)自己的屬性

然而令人感到好奇的是叉存,通過(guò)person這個(gè)對(duì)象可以訪問(wèn)到Person.prototype上的屬性——其實(shí)這是因?yàn)镻erson.prototype是person對(duì)象的原型(就好像是祖先一樣码俩,子孫可以繼承祖先的屬性和方法),這就是person對(duì)象有l(wèi)astName屬性的原因歼捏。

增刪改查講解


  • 原型
實(shí)例對(duì)象

無(wú)論是原型還是實(shí)例對(duì)象都使用統(tǒng)一的方式增加屬性或者方法

        Person.prototype.lastName="deng";
        function Person(name,sex){
            this.name=name;
            this.sex=sex;
        }
        var person = new Person("xiaoliu",'male');
實(shí)例對(duì)象刪除自己的屬性

毫無(wú)疑問(wèn)稿存,實(shí)例對(duì)象可以刪除自己的屬性

實(shí)例對(duì)象刪除原型上的屬性

實(shí)例對(duì)象刪除原型上的屬性返回true,但是沒(méi)有刪除成功瞳秽,這是為什么呢瓣履?看下面演示

刪除person沒(méi)有的屬性

刪除對(duì)象上沒(méi)有的屬性都會(huì)返回ture

原型刪除自己的屬性

結(jié)論
實(shí)例對(duì)象可以刪除自己的屬性,原型可以刪除自己的屬性寂诱,實(shí)例對(duì)象不能刪除原型上的屬性拂苹。至于原型是否可以刪除實(shí)例對(duì)象的屬性——原型上是沒(méi)有實(shí)例對(duì)象的屬性的


  • 兩種方法
    方法一
方法二

第一種情況

先修改原型

成功修改原型上的屬性以及實(shí)例對(duì)象的屬性

后修改實(shí)例對(duì)象

由實(shí)例對(duì)象修改原型中的屬性時(shí)安聘,只能成功修改實(shí)例對(duì)象上的屬性痰洒,原型中的屬性并沒(méi)有被修改

第二種情況

先修改實(shí)例對(duì)象

結(jié)果同上一個(gè)情況一樣

再修改原型屬性

這是你會(huì)發(fā)現(xiàn)此次修改也只是修改原型上的屬性瓢棒,實(shí)例對(duì)象上的屬性并沒(méi)有被修改成功,這是為什么呢丘喻?脯宿?——這是因?yàn)閷?shí)例對(duì)象已經(jīng)擁有自己的顯式屬性,所以修改原型上的屬性并不會(huì)影響實(shí)例對(duì)象的屬性

由于講解需要泉粉,先把__proto __講了
proto用于查看原型的一個(gè)屬性连霉,而且是隱式屬性
栗子栗子

        Person.prototype.name = 'Sunny';
        function Person() {}
        var person = new Person();
image.png

淺紫色表示隱式屬性,深紫色表示顯式屬性

實(shí)例對(duì)象__proto__屬性

原型__proto__

無(wú)論是實(shí)例對(duì)象上的proto還是原型上的proto屬性最終的原型都是Object嗡靡,Object的原型是null跺撼,person.proto==Person.prototype

修改原型上屬性的兩種方式以及它們的不同之處

  • 第一種
 Person.prototype.name = 'Sunny';

        function Person() {}
        Person.prototype.name="Cherry";

        var person = new Person();
結(jié)果
Person.prototype.name = 'Sunny';
        function Person() {}
        var person = new Person();
        Person.prototype.name="Cherry";
結(jié)果

顯而易見(jiàn),上面這兩個(gè)栗子只是原型修改一個(gè)屬性

  • 第二種 稍微變換一下
        Person.prototype.name='sunny';
        function Person() { 
      /*內(nèi)部是這樣子的*/
           //var this={
           //__proto__:Person.prototype
           //}
        var person = new Person();
        Person.prototype={
            name:'cherry'
        }

這個(gè)栗子先創(chuàng)建了一個(gè)實(shí)例對(duì)象讨彼,然后通過(guò)不同的方式修改Person.prototype中的name屬性歉井,猜一猜Person.prototype.name和person.name的值是什么?

結(jié)果

實(shí)例對(duì)象和原型(也是一個(gè)對(duì)象)哈误,它們擁有對(duì)象的特點(diǎn)——存儲(chǔ)的是數(shù)據(jù)的引用哩至,當(dāng)兩個(gè)對(duì)象是同一個(gè)引用時(shí),修改一個(gè)對(duì)象的引用值時(shí)蜜自,不會(huì)影響另外一個(gè)對(duì)象的值∑忻玻現(xiàn)在person.proto和Person.prototype指向同一個(gè)空間,然后Person.prototype換一個(gè)空間重荠,而原來(lái)的person.proto沒(méi)有變箭阶,所以person.name還是為sunny再舉一個(gè)更簡(jiǎn)單的栗子吧~

      var obj = {
            name: 'a'
        };
        var obj1 = obj;
        obj = {
            name: 'b'
        }
結(jié)果

現(xiàn)在應(yīng)該懂了修改引用中的值的妙處了吧~

考一考你

     Person.prototype.name = 'Sunny';
        function Person() {
       /*內(nèi)部是這樣子的*/
           //var this={
           //__proto__:Person.prototype
           //}}
        Person.prototype = {
            name: 'cherry'
        }
        var person = new Person();
結(jié)果

想想預(yù)編譯過(guò)程以及函數(shù)的執(zhí)行順序(什么時(shí)候才調(diào)用構(gòu)造函數(shù))就很容易得出結(jié)果了~

constructor講解
construcor可以查看一個(gè)對(duì)象的構(gòu)造函數(shù)戈鲁,構(gòu)造器是一個(gè)隱式屬性
一個(gè)栗子引入

Person.prototype.name='sunny';
        function Person() {  }
        var person = new Person();


而且constructor可以被修改

  function Car(){}
        
        Person.prototype.name='sunny';
        function Person() {  
            //var this ={
                  //constructor:Person
             //}
}
        var person = new Person();

        person.constructor=Car;
結(jié)果

原型鏈

//Grand.prototype.__proto__->Object.prototype
//Object.prototype.__proto__->null
   Grand.prototype.lastName = "deng";
        function Grand() {}
        var grand = new Grand();

        Father.prototype=grand;
        function Father() {}
        var father = new Father();
        
        Son.prototype=father;
        function Son() {}
        var son = new Son();
       

son實(shí)例對(duì)象查找lastname屬性時(shí)會(huì)根據(jù)原型鏈一層層往上找,直到找到為止尾膊,或者找不到返回undefined

原型鏈上的增刪改查

原型鏈上的增刪改查和原型的增刪改查是差不多的

  • 這里講一個(gè)修改的小特例
    在father身上加一個(gè)引用值
    function Father() {
            this.fortune={
                fo1:"visa"
            }
        }
        var father = new Father();

        Son.prototype=father;
        function Son() {}
        var son = new Son();

這時(shí)通過(guò)son修改fortune


方法一
方法二

上面兩種方式不同,第一種son直接修改person.fortune荞彼,很顯然冈敛,只修改了son.fortune的值,而第二種方式是直接操作fortune引用值鸣皂,顯然是引用值增加一個(gè)屬性抓谴,只是引用值的修改。

補(bǔ)充一個(gè)知識(shí)

 var obj = {}
        var obj1=new Object();
        //obj1._proto_  -->Object.prototype
image.png

第一種var obj = {}是對(duì)象自變量的創(chuàng)建形式寞缝,上面的兩種創(chuàng)建方式是一樣的癌压,用var obj={}的方式系統(tǒng)會(huì)默認(rèn)用new Object()的方式創(chuàng)建,平時(shí)再構(gòu)造對(duì)象時(shí)建議用對(duì)象自變量的創(chuàng)建方式荆陆,即var obj={}

new的作用
1滩届、創(chuàng)建一個(gè)新的對(duì)象
2、將構(gòu)造函數(shù)的this指向這個(gè)新對(duì)象
3被啼、返回這個(gè)新對(duì)象

Object.create()
創(chuàng)建對(duì)象的方法

var obj = Object.create(原型)

 var obj= {name:"sunny",age:123};
        var obj1=Object.create(obj);

obj1的原型就是obj帜消,所以obj1繼承obj的屬性

再舉一個(gè)例子

  Person.prototype.name="sunny";
        function Person(){

        }
        var person=Object.create(Person.prototype);

  Person.prototype.name="sunny";
        function Person(){

        }
     var person=new Person();

的結(jié)果是一樣的棠枉,但是在person的構(gòu)造函數(shù)中定義自己的屬性就不一樣了

一個(gè)錯(cuò)誤的概念
全部對(duì)象最終都會(huì)繼承自O(shè)bject.prototype

正解

對(duì)象的原型只能是一個(gè)Object或者是null,所以我構(gòu)造一個(gè)沒(méi)有原型的對(duì)象泡挺,如下

沒(méi)有原型

結(jié)論
絕大多數(shù)對(duì)象最終都會(huì)繼承自O(shè)bject.prototype辈讶,有的對(duì)象沒(méi)有原型

再補(bǔ)充一下
null和undefiend不能調(diào)用toString()

因?yàn)樗鼈儧](méi)有原型

call/apply

改變this指向
call

function test(){}
test() //其實(shí)執(zhí)行會(huì)默認(rèn)為test.call()

test()和test.call()沒(méi)有區(qū)別

  function Person(name,age){
            //this=obj
            this.name=name;
            this.age=age
        }
        //沒(méi)有new,this指向window
        var person = new Person('deng',100);

        var obj={}
        Person.call(obj,'cheng',200);//第二,三...是參數(shù)

call()就是改變this的指向的娄猫,上面的栗子就是讓obj使用Person的方法構(gòu)造對(duì)象贱除,這時(shí)person構(gòu)造函數(shù)的this為obj,相當(dāng)于obj.name=name,obj.age=age;

傳參
需要把實(shí)參按照形參的個(gè)數(shù)傳進(jìn)去
用法
當(dāng)兩個(gè)對(duì)象含有相同的屬性時(shí)媳溺,但是另一個(gè)對(duì)象的屬性比較多(功能涵蓋)

        function Person(name,age,sex){
            this.name=name;
            this.age=age;
            this.sex=sex;
        }

        function Student(name,age,sex,tel,grade){
            this.name=name;
            this.age=age;
            this.sex=sex;
            this.tel=tel;
            this.grade=grade;
        }
 var student= new Student('Sunny',123,'male',139,2019);

上面構(gòu)造對(duì)象的方式顯得累贅月幌,我們可以用call的方式使用另一個(gè)對(duì)象的構(gòu)造方法

        function Person(name,age,sex){
            this.name=name;
            this.age=age;
            this.sex=sex;
        }

        function Student(name,age,sex,tel,grade){
         Person.call(this,name,age,sex);
            this.tel=tel;
            this.grade=grade;
        }
        var student= new Student('Sunny',123,'male',139,2019);

結(jié)論
對(duì)象名.call(對(duì)象名,參數(shù)...)可以實(shí)現(xiàn)借用別的對(duì)象的屬性來(lái)構(gòu)造本對(duì)象的屬性

apply
使用方式:對(duì)象名.(this,[參數(shù)])
區(qū)別
傳參列表不同悬蔽,call需要把實(shí)參按照形參的個(gè)數(shù)傳進(jìn)去飞醉,apply需要傳一個(gè)arguments

最后看一張圖來(lái)縷一縷自己的思路吧

function Add() {}
var add=new Add();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市屯阀,隨后出現(xiàn)的幾起案子缅帘,更是在濱河造成了極大的恐慌,老刑警劉巖难衰,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钦无,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡盖袭,警方通過(guò)查閱死者的電腦和手機(jī)失暂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鳄虱,“玉大人弟塞,你說(shuō)我怎么就攤上這事∽疽眩” “怎么了决记?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)倍踪。 經(jīng)常有香客問(wèn)我系宫,道長(zhǎng),這世上最難降的妖魔是什么建车? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任扩借,我火速辦了婚禮,結(jié)果婚禮上缤至,老公的妹妹穿的比我還像新娘潮罪。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布嫉到。 她就那樣靜靜地躺著沃暗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屯碴。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天膊存,我揣著相機(jī)與錄音导而,去河邊找鬼。 笑死隔崎,一個(gè)胖子當(dāng)著我的面吹牛今艺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爵卒,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼虚缎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了钓株?” 一聲冷哼從身側(cè)響起实牡,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轴合,沒(méi)想到半個(gè)月后创坞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡受葛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年题涨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片总滩。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纲堵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闰渔,到底是詐尸還是另有隱情席函,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布冈涧,位于F島的核電站向挖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏炕舵。R本人自食惡果不足惜何之,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咽筋。 院中可真熱鬧溶推,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至辐赞,卻和暖如春部翘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背响委。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工新思, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赘风。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓夹囚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親邀窃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荸哟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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