問題7:有如下代碼,解釋Person、 prototype、proto、p、constructor之間的關聯。
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName(); // 'My name is 若愚'
p是Person的實例,所以 p.__proto__=== Person.prototype
,Person.prototype.constructor=== Person
。當調用p.sayName
的時候p先查找自己的屬性中有沒有,沒有就在原型鏈中查找,p.__proto__
指向的和Person.prototype
一樣,Person.prototype
下面有sayName這個函數。原型圖如下:
問題8: 上例中,對對象 p可以這樣調用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
輸入
p.toString
的查找順序,p -> p.__proto__ ->Person.prototype.__proto__->Object.prototype.toString
就像圖中通過
__proto__
連接起來的鏈就叫做原型鏈。
問題9:對String做擴展,實現如下方式獲取字符串中頻率最高的字符
function getMostOften(str){
var obj={};
for(var i=0;i<str.length;i++){
var char=str[i];
if(obj[char]){
obj[char]++;
}else{
obj[char]=1;
}
}
console.log(obj);
var max=0;
var maxChar=null;
for(var key in obj){
if(max<obj[key]){
max=obj[key];
maxChar=key;
}
}
console.log('最多的字符是'+maxChar);
console.log('出現的次數是'+max);
}
問題10: instanceOf有什么作用?內部邏輯是如何實現的?
instanceof 是一個運算符。A instancrof B
用于判斷A 是否是B 的一個實例,或者是A是否是以B為父類型的一個實例。
在上面類Person創建實例p的這個例子中:
p instanceof Person //true
Person instanceof Object //true
p instanceof Object //true
p.__proto__.__proto__===Object.prototype //ture
其內部邏輯是判斷A和B是否處在同一條原型鏈上。代碼如下:
function InstanceOf(a,b){
var proto=a.__proto__;
do{
if(proto === b.prototype){
return true;
}else{
proto=proto.__proto__;
}
}
while(proto)
return false;
}
問題11:繼承有什么作用?
繼承可以使一個對象直接使用另一個對象的方法和屬性。
問題12: 下面兩種寫法有什么區別?
//方法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);
- 在方法1中p1的下面有屬性name和sex,還有方法printName。
- 在方法2中p1下面只有屬性name和sex,printName綁定在其父類Person的prototype屬性下,p1可以繼承父類的屬性和方法,所以仍然可以調用
p1.printName
。
4.jpg
5.jpg
問題13: Object.create 有什么作用?兼容性如何?
Object.create創建一個具有指定原型且可選擇性地包含指定屬性的對象。可以通過Object.create()方法實現類式繼承,如:
Male.prototype = Object.create(Person.prototype);
通過Object.create()
clone了一個新的prototype,使Male.prototype指向這個新的prototype,而不是直接將Person.prototype賦值給它,這樣做可以避免當我修改Male.prototype
的時候不會將它的父類Person.prototype
也修改了。
兼容性
問題14: hasOwnProperty有什么作用? 如何使用?
hasOwnPerperty是Object.prototype的一個方法,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性,hasOwnProperty是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數。
問題15:如下代碼中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex);
this.age = age;
}
call()方法可以將傳入的第一個參數設置為this對象。代碼中在Male
這個類下面執行另一個類Person
可以把Person的屬性 賦值到Male上,但是需要在執行的時候通過call來把環境改到自己的作用域下。
問題16: 補全代碼,實現繼承
function Person(name, sex){
this.name=name;
this.sex=sex;
this.printName=function(){
console.log('Hello, '+name);
}
}
Person.prototype.getName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.call(this,name,sex);
this.age=age;
}
function inherit(superType, subType){
var _prototype = Object.create(superType.prototype);
_prototype.constructor = subType;
subType.prototype = _prototype;
}
inherit(Person, Male);
Male.prototype.getAge = function(){
console.log(this.age);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
ruoyu.getName();