this 原型鏈 繼承

this 相關(guān)問題
問題1: apply、call 、bind有什么作用,什么區(qū)別

共同點(作用): 都是改變函數(shù)this對象的指向,

區(qū)別
call( this, p1, p1,p3)
call()第一個參數(shù)之后的所有參數(shù)都是傳入函數(shù)的值

apply( this, [p1,p2,p3])
apply() 只有兩個參數(shù), 第一個是obj, 第二個是數(shù)組,數(shù)組中是該函數(shù)的參數(shù)

bind() 方法和前兩者不同在于: bind() 方法會返回執(zhí)行上下文被改變的函數(shù)而不會立即執(zhí)行,而前兩者是直接執(zhí)行該函數(shù)。他的參數(shù)和call()相同。

call() apply() 直接t調(diào)用執(zhí)行函數(shù),
bind() 方法會返回執(zhí)行上下文被改變的函數(shù)而不立即執(zhí)行,必須加()才能立即調(diào)用執(zhí)行
bind() 參數(shù)與call() 相同

問題2: 以下代碼輸出什么?

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


/*
john.sayHi= func
sayHi: function func(){}
john.func()
this=== john
john.sayHi()  執(zhí)行函數(shù)
this.firstName='John' 找到自己的屬性
*/

問題3: 下面代碼輸出什么,為什么


func()   //輸出: Window
function func() { 
  alert(this)  //函數(shù)中的this是全局Window對象  因為this 在函數(shù)內(nèi)找不到, 往外找
}

問題4:下面代碼輸出什么

document.addEventListener('click', function(e){
    console.log(this);  // #document
    setTimeout(function(){
        console.log(this);   // Window
    }, 200);
}, false);

問題5:下面代碼輸出什么,why

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john)  //輸出: John

call(參數(shù))  參數(shù)就是要指向的對象this
而 call(john)  john 就是this對象

問題6: 以下代碼有什么問題,如何修改


var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指 $btn
      this.showMsg();
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}
修改: 因為this=$btn , $btn  沒有 showMsg() 方法,
所以不能調(diào)用
var module= {
  bind: function(){
    var  _this= this
    $btn.on('click', function(){
      console.log(this) //this指 $btn
      _this.showMsg();
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}

原型鏈相關(guān)問題

問題7:有如下代碼,解釋Person、 prototype、_proto_、p、constructor之間的關(guān)聯(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();


解釋:
p.__proto__=== Person.prototype
Person.prototype.constructor=== Person

 p 是Person 的實例對象, 擁有Person 的屬性
p.__proto__指向了Person的prototype對象,及找到其中的 sayName()方法
 

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

1 調(diào)用p.toString()

toString()是繼承Object原型對象中定義的toString() 方法。
(1) 首先實例p 會先查找自身有沒有這個方法。
(2) 若沒有, 則通過 p._proto_去找Person.prototype中有沒有toString()。
(3) 還沒有找到, 繼續(xù)往下查找, Person.prototype._proto__指向了Object.prototype, 在prototype中找到了toString()

Paste_Image.png

什么是原型鏈:
由于_proto_是任何對象都有的屬性, 而js 中萬物皆是對象, 所以形成一條_proto_連起來的鏈條,遞歸訪問_proto_必須到頭,并且值為null

問題9:對String做擴(kuò)展,實現(xiàn)如下方式獲取字符串中頻率最高的字符


//原型鏈 一直找到String
String.prototype.getMostofen= function(){
  var dict={};            // 將所有的字符串一次加到 dict,同時為相同值計數(shù)
  for(var i=0; i<this.length; i++){
    if(dict[this[i]]){
      ++dict[this[i]]
      
    }else{
      dict[this[i]]=1
    }
  }
  
  
  var count=0,
      maxValue;
  for(key in dict){
    if(dict[key]>count){
      maxValue= key;
      count= dict[key]
    }
    return maxValue;
  }
  
}


var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現(xiàn)了5次

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

判斷一個對象是不是某個構(gòu)造函數(shù)的實例

p instanceOf Person

查看 p._proto_是不是指向Person
如果沒有, 繼續(xù)查找p._proto_._proto_是不是指向Person ,沒有的話, 繼續(xù)往下查找,直到查找到最終都沒有時, 返回false
查找到,返回 true

繼承相關(guān)問題

問題11:繼承有什么作用?
一個對象可以直接使用另一個對象中的屬性和方法

本身對象可以在繼承的基礎(chǔ)上, 在為自己添加屬性等

問題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);

第一種不管怎么,只要是創(chuàng)建新的對象 就需要直接繼承了這些屬性和 方法, 不管用到?jīng)]有到 ,都會繼承到新的對象中。這樣浪費了 內(nèi)存空間
第二種 是將函數(shù)的方法 放在原型對象中, 這樣想用就可以使用

問題13: Object.create 有什么作用?兼容性如何?

Obiect.create(參數(shù)),
參數(shù)為將創(chuàng)建的一個原型對象, 可以使用指定原型對象中的方法和屬性

student.prototype=Object.create(Person.prototype)

問題14: hasOwnProperty有什么作用? 如何使用?
判斷一個對象中是否包含自定義屬性,而不是 原型鏈上的屬性
很特殊, 是js中唯一一個處理屬性,但是不查找原型鏈的函數(shù)

function Student(){
this.name=name
}
var s= new Student()
s.hasOwnProperty('name') //true
s對象中有沒有自己的屬性name

問題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 直接調(diào)用 Person函數(shù),將Person中的屬性都添加到Male函數(shù)中了
this是 Male的實例

問題16: 補(bǔ)全代碼,實現(xiàn)繼承

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

Person.prototype.getName = function(){
  console.log(this.name)
};    

function Male(name, sex, age){
   this.age= age
   Person.call(this, name,sex)    //獲取對象屬性
}


Male.prototype=Object.create(Person.prototype)  //getName()方法獲取
Male.prototype.construtcor=Male

Male.prototype.printName = function(){
    console.log(this.name+'你好')
};
Male.prototype.getAge = function(){
    console.log(this.age+'歲')
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();
ruoyu.printName();


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容