問題1: apply、call 、bind有什么作用,什么區(qū)別
作用:指定this,改變作用域.
apply與call相似,不同點(diǎn)在于:apply接受數(shù)組作為函數(shù)參數(shù),call函數(shù)執(zhí)行的參數(shù)必須是一個一個添加
bind生成一個新的函數(shù),新函數(shù)中的第一個參數(shù)為thhis指向.
問題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()//John:hi!
this指向要看執(zhí)行時的環(huán)境,本題中john對象的sayHi方法調(diào)用,this指向john這個對象
問題3: 下面代碼輸出什么,為什么
func() //輸出window,在全局作用域執(zhí)行,this指向window
function func() {
alert(this)
}
輸出window,在全局作用域執(zhí)行,this指向window
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);//document
setTimeout(function(){
console.log(this);//window
}, 200);
}, false);
多層this,this指向會變?yōu)轫攲訉ο?,此時應(yīng)該將that=this將this賦值使用或者使用箭頭函數(shù)綁定this
問題5:下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)//John,call改變this指向,指向john這個對象
輸出John
call改變this指向,指向john這個對象
問題6: 以下代碼有什么問題,如何修改
var module= {
bind: function(){
var that = this//將this在這層函數(shù)里將this傳遞給變量
$btn.on('click', function(){
console.log(this) //this指什么,this指向window,多層this,this指向會變?yōu)轫攲訉ο? this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
//修改后
var module= {
bind: function(){
var that = this//將this在這層函數(shù)里將this傳遞給變量
$btn.on('click', function(){
console.log(that)
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();
Person為構(gòu)造函數(shù),prototype為Person的原型屬性,p是Person的實例對象,p的proto指向Person的prototype,constructor指向Person,表面p由Person構(gòu)造而成的
問題8: 上例中,對對象 p可以這樣調(diào)用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。

原型鏈:對象的屬性和方法,有可能是定義在自身,也有可能是定義在它的原型對象。由于原型本身也是對象,又有自己的原型,所以形成了一條原型鏈(prototype chain)。比如,a對象是b對象的原型,b對象是c對象的原型,以此類推。
如果一層層地上溯,所有對象的原型最終都可以上溯到Object.prototype,即Object構(gòu)造函數(shù)的prototype屬性指向的那個對象。那么,Object.prototype對象有沒有它的原型呢?回答可以是有的,就是沒有任何屬性和方法的null對象,而null對象沒有自己的原型。
問題9:對String做擴(kuò)展,實現(xiàn)如下方式獲取字符串中頻率最高的字符
String.prototype.getMostOften = function(){
var string = this
var storeArr = []
var countArr = []
var strArr = string.split('')
strArr.forEach(function(elem){
if (storeArr.indexOf(elem) === -1){
storeArr.push(elem)
countArr[elem] = 1
}else {
countArr[elem] += 1
}
})
var max = 0
var result = []
for (let i in countArr ) {
if (countArr[i] > max){
max = countArr[i]
}
}
for (let j in countArr){
if (countArr[j] === max){
result.push(j)
}
}
return result
}
var str = 'ahbbcccccdeddddfffffg';
var ch = str.getMostOften();
console.log(ch); //c,d,f 因為cdf都出現(xiàn)了5次
問題10: instanceOf有什么作用?內(nèi)部邏輯是如何實現(xiàn)的?
可以判斷某個對象是不是另一個對象的實例。
instanceof 檢測一個對象A是不是另一個對象B的實例的原理是:查看對象B的prototype指向的對象是否在對象A的[[prototype]]鏈上。如果在,則返回true,如果不在則返回false。不過有一個特殊的情況,當(dāng)對象B的prototype為null將會報錯(類似于空指針異常)。
參考鏈接
繼承相關(guān)問題
問題11:繼承有什么作用?
繼承可以讓子類擁有父類的方法和屬性,然后在這個基礎(chǔ)上進(jìn)行方法和屬性調(diào)用,可以提高代碼的復(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);
創(chuàng)造的對象有區(qū)別,方法1中printName是p1實例對象的方法,方法2中printName不是p1實例對象的方法,方法1會重復(fù)創(chuàng)建printName方法,浪費(fèi)內(nèi)存,方法2只會創(chuàng)建一次printName方法可以節(jié)約內(nèi)存。
問題13: Object.create 有什么作用?兼容性如何?
Object.create() 方法會使用指定的原型對象及其屬性去創(chuàng)建一個新的對象。
function Shape() {
this.x = 0;
this.y = 0;
}
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;//創(chuàng)建后一定要修改constructor指向
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true
rect.move(1, 1); //Outputs, "Shape moved."
原因
兼容性:

問題14: hasOwnProperty有什么作用? 如何使用?
hasOwnProperty()方法會返回一個布爾值,指示對象是否具有指定的屬性作為自身(不繼承)屬性。
var o = new Object();
o.prop = 'exists';
o.hasOwnProperty('prop'); // 返回 true
o.hasOwnProperty('toString'); // 返回 false
問題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ù) 第一個參數(shù)this指向Male,使Male函數(shù)實現(xiàn)構(gòu)造函數(shù)繼承,獲取Person下的屬性
問題16: 補(bǔ)全代碼,實現(xiàn)繼承
function Person(name, sex){
this.name = name
this.sex = sex
}
Person.prototype.getName = function(){
return this.name
};
function Male(name, sex, age){
this.age = age
Person.call(this,name,sex)
}
Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male
Male.prototype.getAge = function(){
return this.age
};
var ruoyu = new Male('若愚', '男', 27);
console.log(ruoyu.getName())
console.log(ruoyu.getAge())