問題1: apply、call 蓖康、bind有什么作用铐炫,什么區(qū)別
作用: 改變函數(shù)運行時 this
的指向
區(qū)別:
-
apply
調(diào)用一個函數(shù),傳入函數(shù)執(zhí)行上下文及參數(shù)蒜焊,第一個參數(shù)是希望設置的this
的值倒信,第二個參數(shù)接收參數(shù)數(shù)組 -
call
和apply
很相似,不同之處在于call
接收的不是參數(shù)數(shù)組泳梆,而是參數(shù)列表 -
bind
將函數(shù)內(nèi)部的this
傳入作為參數(shù)鳖悠,并返回一個新函數(shù)唆迁,使用時在需要調(diào)用的地方調(diào)用返回的新函數(shù)
問題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() // John: hi!
問題3: 下面代碼輸出什么,為什么
func()
function func() {
alert(this)
}
輸出 window
函數(shù) func
里的 this
嚴格來說是 undefined
竞穷,按照瀏覽器的規(guī)則「如果你傳的 context 就 null 或者 undefined唐责,那么 window 對象就是默認的 context」, window
就成了默認的 context
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this); // 這里輸出 document 在事件處理程序中瘾带, this 代表事件源 DOM 對象
setTimeout(function(){
console.log(this); // 這里輸出 window 在 setTimeout 和 setInterval 這兩個方法中 this 是全局對象
}, 200);
}, false);
問題5:下面代碼輸出什么鼠哥,why
var john = {
firstName: "John" ![未命名文件.png](http://upload-images.jianshu.io/upload_images/6753264-779f0661d1de04c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
}
function func() {
alert( this.firstName )
}
func.call(john)
輸出 John
函數(shù) func
內(nèi)的 this
是全局對象,在調(diào)用 call
方法并將對象 john
作為 this
的值傳入后看政, func
的 this
指向了對象 john
朴恳,因此得到了上面的輸出結(jié)果
問題6: 以下代碼有什么問題,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
第一個 this
指的是 DOM 元素 $btn
第二個 this
本意是指向?qū)ο?module
允蚣,這樣 this.showMsg()
就可以調(diào)用函數(shù) showMsg
于颖,但由于 $btn
的事件處理程序中的 this
已經(jīng)發(fā)生了變化,預想中的調(diào)用是失敗的
修改如下
var module= {
bind: function(){
var _this = this
$btn.on('click', function(){
console.log(this)
_this.showMsg()
})
},
showMsg: function(){
console.log('饑人谷')
}
}
問題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
是通過函數(shù)定義的類
-
prototype
是類
在創(chuàng)建是自動獲得的屬性 -
constructor
是prototype
屬性下的一個方法(函數(shù))壶运,它又指向類
耐齐,也就是Person
本身 -
p
是Person
的實例 -
__proto__
是實例p
的內(nèi)部屬性,它指向Person
的prototype
屬性
問題8: 上例中蒋情,對對象 p可以這樣調(diào)用 p.toString()埠况。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
首先對象 p
會在自己內(nèi)部尋找 toString()
方法棵癣,找不到時辕翰,就在它的原型 Person
里找,如果原型中也沒有就繼續(xù)向上在原型的原型 Object
里找浙巫,Object
里包含 toString()
方法金蜀, p
也就能夠調(diào)用 toString()
方法了刷后。
每個對象都有屬性和方法的畴,當調(diào)用一個屬性或方法時首先在對象內(nèi)部尋找,如果找不到就向上到該對象的原型中尋找尝胆,如果還找不到丧裁,繼續(xù)向上在原型的原型里尋找,以此類推含衔,直到找到要調(diào)用的屬性或方法煎娇,或者在最頂層原型里也找不到二庵,返回 undefined
。這就是原型鏈
問題9:對String做擴展缓呛,實現(xiàn)如下方式獲取字符串中頻率最高的字符
String.prototype.getMostOften = function(){
var dict = {}
for(var i = 0; i < this.length; i++){
if(dict[this[i]]){
dict[this[i]]++
}else{
dict[this[i]] = 1
}
}
var count = 0
var maxChar
for(var key in dict){
if(dict[key] > count){
maxChar = key
count = dict[key]
}
}
return maxChar
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現(xiàn)了5次
問題10: instanceOf有什么作用催享?內(nèi)部邏輯是如何實現(xiàn)的?
instanceof
用于判斷一個對象是不是某個類的實例
例如在 a instanceof b
中哟绊, a
通過 __proto__
屬性一層層向上尋找因妙,看是否能找到原型 b
,如果能找到票髓, a
就是 b
的實例攀涵,反之則不是
問題11:繼承有什么作用?
繼承可以讓一個對象直接使用另一個對象的屬性和方法
問題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);
在方法1中,方法 printName
定義在類 People
里洽沟,每次創(chuàng)建 People
的實例都要重新創(chuàng)建一次該方法以故,損耗了一部分性能
而方法2將方法 printName
綁定到 People.prototype
上,再創(chuàng)建實例時裆操,都可以在需要的時候調(diào)用該方法怒详,而不必每次都創(chuàng)建方法,即使不使用這個方法也不得不創(chuàng)建踪区,節(jié)省了內(nèi)存空間棘利,提高了性能
問題13: Object.create 有什么作用?兼容性如何朽缴?
Object.create()
方法會使用指定的原型對象及其屬性去創(chuàng)建一個新的對象善玫。
Object.create()
是ES5方法,不兼容IE9以下
問題14: hasOwnProperty有什么作用? 如何使用密强?
hasOwnProperty
是 Object.prototype
的一個方法茅郎,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性, hasOwnProperty
是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數(shù)
例如要判斷對象 o
的屬性是自身屬性還是繼承屬性或渤,可以這樣做
o = new Object();
o.prop = 'exists';
o.hasOwnProperty('prop'); // 返回 true
o.hasOwnProperty('toString'); // 返回 false
o.hasOwnProperty('hasOwnProperty'); // 返回 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;
}
通過在類 Male
中執(zhí)行類 Person
的構(gòu)造函數(shù)系冗,就把 Person
到屬性賦值到了 Male
內(nèi)部,現(xiàn)在 Male
也可以調(diào)用 Person
到屬性和方法了
問題16: 補全代碼薪鹦,實現(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();