this 相關(guān)問(wèn)題
apply、call 、bind有什么作用,什么區(qū)別
apply和call的作用非常相似,調(diào)用一個(gè)函數(shù),傳入函數(shù)執(zhí)行上下文及參數(shù)
第一個(gè)參數(shù)是希望設(shè)置的this對(duì)象
- apply 接收參數(shù)數(shù)組
- call 接收參數(shù)列表
- bind 返回一個(gè)新函數(shù),并且使函數(shù)內(nèi)部的this為傳入的第一個(gè)參數(shù)
以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()//輸出 John:hi! this指向調(diào)用sayHi的john對(duì)象
下面代碼輸出什么,為什么
func()
function func() {
alert(this)//輸出window 因?yàn)樵诤瘮?shù)被直接調(diào)用時(shí)this綁定到全局對(duì)象。在瀏覽器中,window 就是該全局對(duì)象
}
下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);//輸出document,在事件處理程序中this代表事件源DOM對(duì)象
setTimeout(function(){
console.log(this);//輸出 window,setTimeout下,this仍指向全局對(duì)象window
}, 200);
}, false);
下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)//John .call()為函數(shù)指定了執(zhí)行環(huán)境john
以下代碼有什么問(wèn)題,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) // this指什么$btn
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
bind屬性中,this.showMsg()語(yǔ)句的this指的是$btn,是無(wú)法調(diào)用showMsg()的,
此時(shí)需要保存事件綁定函數(shù)外部的this,修改后:
var module= {
bind: function(){
var _this = this
$btn.on('click', function(){
console.log(this)
_this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
原型鏈相關(guān)問(wèn)題
有如下代碼,解釋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的一個(gè)實(shí)例對(duì)象,p里的proto指向Person的prototype里,Person的prototype里的proto指向Object的prototype,Person的prototype里的constructor既是Person本身
上例中,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()。toString是哪里來(lái)的? 畫(huà)出原型圖?并解釋什么是原型鏈。

p.toString()是在p.proto.proto里,在 javaScript 中,每個(gè)對(duì)象都有一個(gè)指向它的原型(prototype)對(duì)象。這個(gè)原型對(duì)象又有自己的原型,直到某個(gè)對(duì)象的原型為 null 為止(也就是不再有原型指向),組成這條鏈的最后一環(huán)。這種一級(jí)一級(jí)的鏈結(jié)構(gòu)就稱為原型鏈(prototype chain)。
對(duì)String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符
String.prototype.getMostOften=function(){
var obj = {}
for(var i = 0,j;i<this.length;i++){
j = this[i]
if(obj[j]){
obj[j]++
}else{
obj[j] = 1
}
}
var max=0
var key=0
for(var k in obj){
if(obj[k]>max){
max = obj[k]
key = k
}
}
return key
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因?yàn)閐 出現(xiàn)了5次
instanceOf有什么作用??jī)?nèi)部邏輯是如何實(shí)現(xiàn)的?
instanceOf:運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性
function instanceOf(obj,fn){
var objpro = obj.__proto__;
while(objpro){
if(objpro === fn.prototype){
return true;
}else{
objpro = objpro.__proto__;
}
}
return false;
}
繼承相關(guān)問(wèn)題
繼承有什么作用?
- 概念:繼承是指一個(gè)對(duì)象直接使用另一個(gè)對(duì)象的屬性和方法。
- 作用:繼承劃分了類的層次性,父類代表的是更一般、更泛化的類,而子類則是更為具體、更為細(xì)化;繼承是實(shí)現(xiàn)代碼重用、擴(kuò)展軟件功能的重要手段,子類中與父類完全相同的屬性和方法不必重寫(xiě),只需寫(xiě)出新增或改寫(xiě)的內(nèi)容,這就是說(shuō)子類可以復(fù)用父類的內(nèi)容,不必一切從零開(kāi)始。
下面兩種寫(xiě)法有什么區(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);
區(qū)別:都是創(chuàng)建printName方法,方法1的printName方法是在函數(shù)Person實(shí)例對(duì)象里的,方法2是在Person的prototype對(duì)象上的。當(dāng)創(chuàng)建一個(gè)Person實(shí)例對(duì)象的時(shí)候,方法1又將會(huì)再創(chuàng)建一個(gè)printName方法,占用新的內(nèi)存,而方法2將一個(gè)公用的printName方法寫(xiě)在原型上,當(dāng)對(duì)象要使用該方法只需到原型鏈里調(diào)用就可以了,達(dá)到節(jié)省內(nèi)存的效果。
Object.create 有什么作用?兼容性如何?
作用:創(chuàng)建一個(gè)擁有指定原型和若干個(gè)指定屬性的對(duì)象。
兼容:

使用:
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.getName=function(){
console.log(this.name)
}
function Male(name,age,sex){
Person.call(this,name,age)
this.sex=sex
}
Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male
Male.prototype.getSex=function(){
console.log(this.sex)
}
var m = new Male('Nick',7,'boy')
m.getName() //Nick
hasOwnProperty有什么作用? 如何使用?
- 作用:hasOwnPerperty是Object.prototype的一個(gè)方法,可以判斷一個(gè)對(duì)象是否包含自定義屬性而不是原型鏈上的屬性
- 語(yǔ)法:obj.hasOwnProperty(prop)(prop為要檢測(cè)的屬性名稱)
- 使用(以上一題為例):
m.hasOwnProperty('name');//true
m.hasOwnProperty('getName');//false
m.prototype.hasOwnProperty('getSex');//true
如下代碼中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 的作用是將執(zhí)行上下文的環(huán)境切換到Person下,也就是將Person的屬性賦值給Male
補(bǔ)全代碼,實(shí)現(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){
Person.call(this,name,sex)
this.age=age
}
Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male
Male.prototype.getAge = function(){
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();