作業(yè)
this 相關(guān)問題
-
問題1: apply、call 有什么作用,什么區(qū)別
- apply()和call()函數(shù)都可以 指定this值和參數(shù)值的情況下調(diào)用某個函數(shù)。
- call()和apply()的作用一樣,區(qū)別在于提供給原函數(shù)的參數(shù)的方式不一樣.
- pply()函數(shù)只接受兩個參數(shù),提供給原函數(shù)的參數(shù)以數(shù)組或類數(shù)組對象的形式存在.
- 而call()接收無限個參數(shù), 第二個參數(shù)及其后面的參數(shù)就是提供給原函數(shù)的參數(shù)。
-
問題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()//彈出john:hi!
//因?yàn)閒unc賦給了john對象的sayHi屬性,執(zhí)行john.sayHi() 時(shí) 是在john對象上調(diào)用的,此時(shí)的上下文this是john了.
* 問題3: 下面代碼輸出什么,為什么?
```
func() //彈出window ,因?yàn)榇藭r(shí)函數(shù)里的this歸根結(jié)底是window調(diào)用的
function func() {
alert(this)
}
-
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);//會打印document 因?yàn)檫@個屬于綁定事件類型,此時(shí)的this指的是事件源DOM對象
setTimeout(function(){
console.log(this);//setTimeout及setInterval里的this均指window
}, 200);
}, false);
* 問題5:下面代碼輸出什么,why
```
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)//彈出John,因call(john)就是把函數(shù)執(zhí)行的上下文及參數(shù)John傳給func函數(shù)。此時(shí)firstName: "John",所以this.firstName肯定是“John”了。
-
問題6: 以下代碼有什么問題,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指的是$btn源DOM對象
this.showMsg();//此處應(yīng)該改為module.showMsg(),不改的話它會在$btn源DOM對象找showMsg().會導(dǎo)致this.showMsg is not a function 報(bào)錯
})
},
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是Person的實(shí)例,所以繼承Person原型鏈上的屬性和方法。
//關(guān)聯(lián):
Person.prototype.constructor == Person,
Person.prototype == p.__proto__,
p.__proto__.constructor == Person,
Person.prototype.__proto__ == Object.prototype,
Object.prototype.constructor == Object,
Object.prototype.__proto__ == null
-
問題8: 上例中,對對象 p可以這樣調(diào)用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
答:構(gòu)造函數(shù)的原型自帶一個指針指向object的原型,因而toString是從object的原型里繼承而來。Paste_Image.png
原型鏈:JS在創(chuàng)建對象(不論是普通對象還是函數(shù)對象)的時(shí)候,都有一個叫做proto的內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對象的原型對象prototype。在訪問一個對象屬性的時(shí)候,如果對象本身沒有找到這個屬性,就會沿著原型鏈一層一層的尋找。 -
問題9:對String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因?yàn)閐 出現(xiàn)了5次
String.prototype.getMostOften = function(){
var obj = {};
for(var i=0,k;i<this.length;i++){
k = this[i];
if(obj[k]){
obj[k]++
}else{
obj[k] = 1
}
}
var max = 0,key;
for(var k in obj){
if(obj[k]>max){
max = obj[k];
key = k;
}
}
return key;
}
* 問題10: instanceOf有什么作用?內(nèi)部邏輯是如何實(shí)現(xiàn)的?
答:
作用是確認(rèn)instanceOf前面的對象是否是后面的對象的實(shí)例;
##繼承相關(guān)問題
* 問題11:繼承有什么作用?
答:
繼承使不同的實(shí)例可以共享構(gòu)造函數(shù)的原型對象的屬性和方法,以提高代碼的復(fù)用性;
* 問題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);
//printName:一個寫在構(gòu)造函數(shù)內(nèi)部的實(shí)例對象上。另一個寫在構(gòu)建函數(shù)的prototype對象上。
//前者在每生成一個實(shí)例之后實(shí)例的printName就新占用內(nèi)存。
//后者每生成一個實(shí)例后會共享構(gòu)造函數(shù)prototype對象上的printName方法,以達(dá)到節(jié)省內(nèi)存的效果;
- 問題13: Object.create 有什么作用?兼容性如何?
答:Object.create()是ES5提出的一個新的方法,它可以傳入一個對象作為該方法返回的對象的原型對象;
-
兼容性:各大瀏覽器的最新版本(包括IE9)都兼容了這個方法。如果遇到老式瀏覽器,可以用下面的代碼兼容:
if(!Object.create){
Object.create = function(obj){
function F(){};
F.prototype = obj;
return new F();
}
}
* 問題14: hasOwnProperty有什么作用? 如何使用?
答:
對象實(shí)例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。
var people = {
name:'teren'
}
people.hasOwnProperty('name')//true
people.hasOwnProperty('toString')//false
Object.getPrototypeOf(people).hasOwnProperty('toString')//true
* 問題15:如下代碼中call的作用是什么?
```
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //這里的 call 有什么作用
////構(gòu)造函數(shù)Person在構(gòu)造函數(shù)Male作用域下執(zhí)行,以實(shí)現(xiàn)構(gòu)造函數(shù)的繼承;
this.age = age;
}
-
問題16: 補(bǔ)全代碼,實(shí)現(xiàn)繼承
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
return 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;
Male.prototype.getAge = function(){
return this.age
};
Male.prototype.getAge = function(){
console.log(this.name)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
