原型鏈相關(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();
person
是構(gòu)造函數(shù)忿等;
prototype
是構(gòu)造函數(shù)的原型對(duì)象;
p
是構(gòu)造函數(shù)的實(shí)例崔挖;
__proto__
是p
的原型鏈贸街,指向person
的prototype
;
constructor
即構(gòu)造函數(shù)person
本身狸相。
問題8: 上例中薛匪,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()蝌焚。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈掖蛤。
- toString是哪里來的?
p首先會(huì)找自己的toString
方法,如果未找到就會(huì)通過__proto__
到pcrson
的prototype
上尋找素标,如果未找到瘸右,就會(huì)繼續(xù)通過prototype
的__proto__
到object.prototype
上尋找娇跟,結(jié)果會(huì)找到toString
方法。 - 解釋什么是原型鏈
JS在創(chuàng)建對(duì)象(不論是普通對(duì)象還是函數(shù)對(duì)象)的時(shí)候太颤,都有一個(gè)叫做__proto__
的內(nèi)置屬性苞俘,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype
。在訪問一個(gè)對(duì)象屬性的時(shí)候龄章,如果對(duì)象本身沒有找到這個(gè)屬性吃谣,就會(huì)沿著原型鏈一層一層的尋找乞封。
問題9:對(duì)String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符
String.prototype.getMostOften = function (){
var obj = {};
for(var i=0;i<this.length;i++){
var k = this[i];
if(!obj[k]){
obj[k] = 1;第一次出現(xiàn) 次數(shù)記為1
}else{
obj[k]++;// 如果存在次數(shù)再加1
}
}
console.log(obj);
//遍歷對(duì)象岗憋,找到出現(xiàn)次數(shù)最多的
var max = 0,val;
for(var key in obj){
if(obj[key] > max){
max = obj[key];
val = key;
}
}
return ('因?yàn)?+val+'出現(xiàn)了'+max+'次');
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因?yàn)閐 出現(xiàn)了5次
問題10: instanceOf有什么作用肃晚?內(nèi)部邏輯是如何實(shí)現(xiàn)的?
- instanceOf:判斷一個(gè)對(duì)象是否為另一個(gè)對(duì)象的實(shí)例仔戈。繼承中判斷實(shí)例是否屬于它的父類
繼承相關(guān)問題
問題11:繼承有什么作用?
- 在訪問對(duì)象上的一個(gè)屬性時(shí)关串,他會(huì)在原型鏈上尋找該屬性,一直找到原型鏈的末端杂穷,所以我們?cè)谠玩溕咸砑拥姆椒ê凡瑢?shí)例可以使用,也就是繼承耐量。
- 繼承可以減少重復(fù)的代碼飞蚓。比如父類已經(jīng)提供的方法,子類可以直接使用廊蜒,不必再去實(shí)現(xiàn)趴拧。
問題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);
方法一是在People函數(shù)內(nèi)部創(chuàng)建printName方法,當(dāng)再創(chuàng)建一個(gè)People時(shí)山叮,printName方法又會(huì)被創(chuàng)建一次著榴,所以比較消耗內(nèi)存。
方法二的printName方法是放在Person的原型上屁倔,當(dāng)需要使用的時(shí)候調(diào)用就可以了脑又,不需要重復(fù)創(chuàng)建printName方法。
問題13: Object.create 有什么作用锐借?兼容性如何问麸?
- Object.create() 方法創(chuàng)建一個(gè)擁有指定原型和若干個(gè)指定屬性的對(duì)象。
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('My name is :' + this.name);
}
function People(name){
this.name = name;
}
People.prototype = Object.create(Person.prototype);
People.prototype.constructor = People;
var p = new People('若愚');
p.sayName();
- 通過
Object.create()
方法钞翔,讓People.prototype
指向Person.prototype
繼承它的printName
方法严卖。 - 對(duì)
People.prototype
進(jìn)行修改不會(huì)影響到原來Person.prototype
的printName
方法。 - 兼容性:
問題14: hasOwnProperty有什么作用布轿? 如何使用哮笆?
hasOwnProperty() 方法會(huì)返回一個(gè)布爾值,其用來判斷某個(gè)對(duì)象是否含有指定的屬性汰扭,該方法會(huì)忽略掉那些從原型鏈上繼承到的屬性稠肘。
問題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;
}
在Male
下執(zhí)行Person
環(huán)境,Male
繼承了Person
的功能东且。
問題16: 補(bǔ)全代碼启具,實(shí)現(xiàn)繼承
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
console.log(this.name);
};
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this,name,sex);
this.age = age;
}
Male.prototype = Object.create(Person.prototype); //ES5的方法
Male.prototype.constructor = Male;
Male.prototype.getAge = function(){
console.log(this.name);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
方法二:
function fn () {}
fn.prototype = Person.prototype
Male.prototype = new fn()