this之拨、原型鏈、繼承

深入詳解javascript之delete操作符
深入javascript(六):instanceof 運算符
重新理解JS的6種繼承方式
JS 的 new 到底是干什么的咧叭?

1.apply蚀乔、call 、bind有什么作用菲茬,什么區(qū)別

  • 這三個函數(shù)主要作用在于改變this的指向吉挣。

  • call:傳遞一個thisArgs參數(shù)和一個參數(shù)列表,thisArgs 指定了函數(shù)在運行期的調(diào)用者婉弹,也就是函數(shù)中的 this 對象睬魂,而參數(shù)列表會被傳入調(diào)用函數(shù)中,如:

    var a = {
    
         name:'onepixel', //定義a的屬性
    
        say:function(){ //定義a的方法
            console.log("Hi,I'm function a!");
        }
    };
    
    function b(name){
        console.log("Post params: "+ name);
        console.log("I'm "+ this.name);
        this.say();
    }
    
    b.call(a,'test');
    >>>
    Post params: test
    I'm onepixel
    I'm function a!
    
  • apply:和call效果相似,只是第二個參數(shù)傳遞的是數(shù)組

     function b(x,y,z){
       console.log(x,y,z);
     }
     b.apply(null,[1,2,3]); // 1 2 3
    
  • bind:ES5引入 bind 的真正目的是為了彌補 call/apply 的不足镀赌,由于 call/apply 會對目標函數(shù)自動執(zhí)行氯哮,從而導致它無法在事件綁定函數(shù)中使用,因為事件綁定函數(shù)不需要我們手動執(zhí)行商佛,它是在事件被觸發(fā)時由JS 內(nèi)部自動執(zhí)行的喉钢。而 bind 在實現(xiàn)改變函數(shù) this 的同時又不會自動執(zhí)行目標函數(shù)
    var obj = {name:'onepixel'};

    /**
    * 給document添加click事件監(jiān)聽,并綁定onClick函數(shù)
    * 通過bind方法設置onClick的this為obj良姆,并傳遞參數(shù)p1,p2
    */
     document.addEventListener('click',onClick.bind(obj,'p1','p2'),false);
    
     //當點擊網(wǎng)頁時觸發(fā)并執(zhí)行
     function onClick(a,b){
         console.log(
               this.name, //onepixel
               a, //p1
               b  //p2
         )
     }  
    

2.以下代碼輸出什么?

  var john = { 
    firstName: "John" 
  }
  function func() { 
    alert(this.firstName + ": hi!")
  }
  john.sayHi = func
  john.sayHi()   //john:hi

3.下面代碼輸出什么肠虽,為什么

  func() 
  function func() { 
    alert(this)
  }    //代碼輸出為window
  • 因為func函數(shù)為全局變量,相當于window.func() 或者是 func.call(undefined)

4.下面代碼輸出什么

  document.addEventListener('click', function(e){
      console.log(this);    //  這個this為document
      setTimeout(function(){
          console.log(this);    // setTimeout玛追、setInterval函數(shù)的全局對象為window
      }, 200);
  }, false);

5.下面代碼輸出什么税课,why

  var john = { 
      firstName: "John" 
  }

  function func() { 
      alert( this.firstName )
  }
  func.call(john)    //  John
  • 因為使用了call方法,該方法將func的this轉(zhuǎn)向為john

6.以下代碼有什么問題痊剖,如何修改

  var module= {
    var _this = this   //  將this賦值給_this
    bind: function(){
      $btn.on('click', function(){
        console.log(this)   //  this 指 $btn
        this.showMsg();    //  修改為_this.showMsg
      })
    },

    showMsg: function(){
      console.log('饑人谷');
    }
  }

7.有如下代碼韩玩,解釋Person、 prototype邢笙、proto啸如、p、constructor之間的關聯(lián)氮惯。

   function Person(name){
       this.name = name;
   }
   Person.prototype.sayName = function(){
       console.log('My name is :' + this.name);
   }
   var p = new Person("若愚")
   p.sayName();
  • Person是一個構造函數(shù)叮雳,當new Person()的時候會創(chuàng)建一個空對象想暗,然后將空對象的__proto__指向prototype,再將返回值賦值給p(實例對象)帘不,對象的constructor屬性用于返回創(chuàng)建該對象的函數(shù)说莫,也就是我們常說的構造函數(shù)

8.上例中,對對象 p可以這樣調(diào)用 p.toString()寞焙。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈储狭。

  • p.toString()方法是繼承構造函數(shù)Object的原型對象里定義的toString方法,首先p會找自己的toString方法捣郊,如果沒有找到辽狈,會沿著__proto__屬性繼續(xù)到構造函數(shù)Person的prototype里找toString方法,如果還未找到呛牲,再繼續(xù)往Person.prototype的__proto__即Object.prototype找toString方法刮萌,最后找到toString()方法。
  • 原型鏈:由于原型對象本身也是對象娘扩,而每個javascript對象都有一個原型對象着茸,每個對象都有一個隱藏的proto屬性,原型對象也有自己的原型琐旁,而它自己的原型對象又可以有自己的原型涮阔,這樣就組成了一條鏈,這個就是原型鏈灰殴。在訪問對象的屬性時敬特,如果在對象本身中沒有找到,則會去原型鏈中查找验懊,如果找到擅羞,直接返回值,如果整個鏈都遍歷且沒有找到屬性义图,則返回undefined减俏。原型鏈一般實現(xiàn)為一個鏈表,這樣就可以按照一定的順序來查找碱工。
3704824-d6cbc01eac70a205.png

9.對String做擴展娃承,實現(xiàn)如下方式獲取字符串中頻率最高的字符

    // 方法一: 
    String.prototype.getMostOften = function(){
        var obj = {};
        for(var i = 0; i < this.length; i++){
            if(obj[this[i]]){
                obj[this[i]]++;
            }else{
                obj[this[i]] = 1;
            }
        }

        var count = 0,key;
        for(var k in obj){
            if(obj[k] > count){
                count = obj[k];
                key = k
            }
        }

        return key + ',出現(xiàn)次數(shù):' + count
    }
    
    var str = 'ahbbccdeddddfg';
    var ch = str.getMostOften();
    console.log(ch); //d , 因為d 出現(xiàn)了5次

    //  方法二:
    String.prototype.getMostOften = function(){
        var arr = this.split('');
        var obj = arr.reduce(function(init,value){
            if(init[value]){
                init[value]++;
            }else{
                init[value] = 1;
            }

            return init;
        },{})

        var count = 0,key;
        for(var k in obj){
            if(obj[k] > count){
                count = obj[k];
                key = k;
            }
        }

        return key + '怕篷,出現(xiàn)次數(shù):' + count
    }

    
    
    var str = 'ahbbccdeddddfg';
    var ch = str.getMostOften();
    console.log(ch);

10.instanceOf有什么作用历筝?內(nèi)部邏輯是如何實現(xiàn)的?

instanceof運算符可以用來判斷某個構造函數(shù)的prototype屬性是否存在另外一個要檢測對象的原型鏈上廊谓。

  function instanceOf(obj,fn){
    var oldpro = obj.__proto__;
    while(oldpro){
      if(oldpro === fn.prototype){
          return true;
          break;
      }else{
          oldpro = oldpro.__proto__;
      }
    }
    return false;
  }

11.繼承有什么作用?

  • 概念:繼承是指一個對象直接使用另一個對象的屬性和方法梳猪。
  • 作用:繼承劃分了類的層次性,父類代表的是更一般蒸痹、更泛化的類春弥,而子類則是更為具體呛哟、更為細化;繼承是實現(xiàn)代碼重用匿沛、擴展軟件功能的重要手段扫责,子類中與父類完全相同的屬性和方法不必重寫,只需寫出新增或改寫的內(nèi)容逃呼,這就是說子類可以復用父類的內(nèi)容鳖孤,不必一切從零開始

12.下面兩種寫法有什么區(qū)別?

  //方法1
  function People(name, sex){
      this.name = name;
      this.sex = sex;
      this.printName = function(){
          console.log(this.name);
      }
  }
  var p1 = new People('饑人谷', 2)

  //方法2
  function Person(name, sex){
      this.name = name;
      this.sex = sex;
  }

  Person.prototype.printName = function(){
      console.log(this.name);
  }
  var p1 = new Person('若愚', 27);
  • 區(qū)別:同樣都是創(chuàng)建printName方法,方法1的printName方法是在函數(shù)Person實例對象里的抡笼,方法2是在Person的prototype對象上的苏揣。當再創(chuàng)建一個Person實例對象的時候,方法1又將會再創(chuàng)建一個printName方法蔫缸,占用新的內(nèi)存腿准,而方法2將一個公用的printName方法寫在原型上,當對象要使用該方法只需到原型鏈里調(diào)用就可以了拾碌,達到節(jié)省內(nèi)存的效果

13.Object.create 有什么作用?兼容性如何街望?

  • Object.create() 方法使用指定的原型對象和其屬性創(chuàng)建了一個新的對象校翔。

  • 不支持IE8以下瀏覽器

    function Person(name, age){
        this.name = name;
        this.age = age;
    }
    Person.prototype.sayName = function(){
        console.log(this.name);
    }
    function Male(name, age, sex){
        Person.call(this, name, age);
        this.sex = sex;
    }
    // Male.prototype = new Person(); //該方法同下,代替不兼容Object.create()的使用場景
    Male.prototype = Object.create(Person.prototype);
    Male.prototype.constructor = Male;
    Male.prototype.sayAge = function(){
          console.log(this.age);
    };
    var p1 = new Male('hunger', 20, 'nan');
    p1.sayName();//hunger
    p1.sayAge();//20
    

14.hasOwnProperty有什么作用灾前? 如何使用防症?

  • hasOwnPerperty是Object.prototype的一個方法,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性哎甲,hasOwnProperty是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數(shù)

  • 此方法不會檢查對象的原型鏈中是否存在該屬性蔫敲,該屬性只有是對象本身的一個成員才會返回true

    function Site(){
        this.name = "CodePlayer";
        this.url = "http://www.365mini.com/";
    
        this.sayHello = function(){
            document.writeln("歡迎來到" + this.name);
        };
    }
    
    var obj = {
        engine: "PHP",
        sayHi: function(){
            document.writeln("歡迎訪問" + this.url);
        }
    };
    // 使用對象obj覆蓋Site本身的prototype屬性
    Site.prototype = obj;
    
    var s =  new Site();
    document.writeln( s.hasOwnProperty("name") ); // true
    document.writeln( s.hasOwnProperty("sayHello") ); // true
    // 以下屬性繼承自原型鏈,因此為false
    document.writeln( s.hasOwnProperty("engine") ); // false
    document.writeln( s.hasOwnProperty("sayHi") ); // false
    document.writeln( s.hasOwnProperty("toString") ); // false
    
    // 想要查看對象(包括原型鏈)是否具備指定的屬性炭玫,可以使用in操作符
    document.writeln( "engine" in s ); // true
    document.writeln( "sayHi" in s ); // true
    document.writeln( "toString" in s ); // true
    

15.如下代碼中call的作用是什么?

  function Person(name, sex){
      this.name = name;
      this.sex = sex;
  }
  function Male(name, sex, age){
      Person.call(this, name, sex);    //這里的 call 有什么作用
      this.age = age;
  }
  • call的作用是將構造函數(shù)Person的this指向Male奈嘿,使得Male擁有Person的屬性

16.補全代碼,實現(xiàn)繼承

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

    Person.prototype.getName = function(){
        console.log('My name is' + this.name)
    };    

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

    Male.prototype = Object.create(Person.prototype);
    Male.prototype.constructor = Male
    // 兼容寫法:
    // function Temp(){}
    // Temp.prototype = Person.prototype
    // Male.prototype = new Temp()

    Male.prototype.getAge = function(){
        console.log('My age is' + this.age)
    };
    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.printName();
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吞加,一起剝皮案震驚了整個濱河市裙犹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衔憨,老刑警劉巖叶圃,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異践图,居然都是意外死亡掺冠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門码党,熙熙樓的掌柜王于貴愁眉苦臉地迎上來德崭,“玉大人悍及,你說我怎么就攤上這事〗影” “怎么了心赶?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缺猛。 經(jīng)常有香客問我缨叫,道長,這世上最難降的妖魔是什么荔燎? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任耻姥,我火速辦了婚禮,結果婚禮上有咨,老公的妹妹穿的比我還像新娘琐簇。我一直安慰自己,他們只是感情好座享,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布婉商。 她就那樣靜靜地躺著,像睡著了一般渣叛。 火紅的嫁衣襯著肌膚如雪丈秩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天淳衙,我揣著相機與錄音蘑秽,去河邊找鬼。 笑死箫攀,一個胖子當著我的面吹牛肠牲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播靴跛,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼缀雳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了汤求?” 一聲冷哼從身側響起俏险,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扬绪,沒想到半個月后竖独,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡挤牛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年莹痢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡竞膳,死狀恐怖航瞭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坦辟,我是刑警寧澤刊侯,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布择同,位于F島的核電站褒脯,受9級特大地震影響拌夏,放射性物質(zhì)發(fā)生泄漏列敲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一并巍、第九天 我趴在偏房一處隱蔽的房頂上張望咐扭。 院中可真熱鬧子寓,春花似錦梁厉、人聲如沸辜羊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽八秃。三九已至,卻和暖如春计技,著一層夾襖步出監(jiān)牢的瞬間喜德,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工垮媒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人航棱。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓睡雇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饮醇。 傳聞我的和親對象是個殘疾皇子它抱,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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

  • 1. apply、call 朴艰、bind有什么作用观蓄,什么區(qū)別? call ,apply的作用:調(diào)用一個函數(shù)祠墅,傳入函數(shù)...
    Rising_suns閱讀 395評論 0 0
  • this 相關問題 問題1: apply侮穿、call 有什么作用,什么區(qū)別 Javascript的每個Functio...
    Maggie_77閱讀 595評論 0 0
  • apply毁嗦、call 亲茅、bind有什么作用,什么區(qū)別 apply:fn.apply( obj,])將fn函數(shù)里的t...
    邵志遠閱讀 493評論 0 0
  • 1. this2.原型鏈-instanceof實現(xiàn)3.繼承的實現(xiàn) ** this 相關問題 ** ** 1验残、 ap...
    饑人谷_阿靖閱讀 353評論 0 0
  • 1: apply、call 巾乳、bind有什么作用您没,什么區(qū)別 call 和 apply 都是為了改變某個函數(shù)運行時的...
    高進哥哥閱讀 256評論 0 0