this 相關(guān)問題
問題1: apply抬探、call 、bind有什么作用帆赢,什么區(qū)別
apply() 方法調(diào)用一個函數(shù), 其具有一個指定的this值小压,以及作為一個數(shù)組(或類似數(shù)組的對象)提供的參數(shù)。
fun.apply(thisArg, [argsArray])
// thisArg 在 fun 函數(shù)運行時指定的 this 值椰于。
// argsArray 一個數(shù)組或者類數(shù)組對象
call() 方法調(diào)用一個函數(shù), 其具有一個指定的this值和分別地提供的參數(shù)(參數(shù)的列表)怠益。
fun.call(thisArg[, arg1[, arg2[, ...]]])
// thisArg在fun函數(shù)運行時指定的this值。
// arg1, arg2, ...指定的參數(shù)列表瘾婿。
bind()方法創(chuàng)建一個新的函數(shù), 當被調(diào)用時蜻牢,將其this關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時偏陪,在任何提供之前提供一個給定的參數(shù)序列抢呆。
fun.bind(thisArg[, arg1[, arg2[, ...]]])
// thisArg 當綁定函數(shù)被調(diào)用時,該參數(shù)會作為原函數(shù)運行時的 this 指向笛谦。當使用new操作符調(diào)用綁定函數(shù)時抱虐,該參數(shù)無效。
// arg1, arg2, ...指定的參數(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)
}
// 瀏覽器彈出提示:[Object window] this是指調(diào)用函數(shù)的對象懦冰,若無指定對象,則默認為window
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
// #document
// window setTimeout的函數(shù)里的this是全局變量
問題5:下面代碼輸出什么谣沸,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
// John 因為call的作用是將括號內(nèi)的john指定為this來調(diào)用func
問題6: 以下代碼有什么問題儿奶,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
// this指向的不是對象實例,它不包含showMsg屬性
修改
var module= {
bind: function(){
var __this = this
$btn.on('click', function(){
console.log(__this) //this指什么
__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ù)贤重,p 是 Person 的實例對象
// prototype是p的對象原型茬祷,p從prototype繼承方法sayName,p的__proto__指向其構(gòu)造函數(shù)的prototype
// constructor屬性在prototype對象中并蝗,默認指向prototype對象所在的構(gòu)造函數(shù)
問題8: 上例中祭犯,對對象 p可以這樣調(diào)用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈滚停。
從Object()中繼承來沃粗。p.proto.proto.toString()
原型鏈: 對象的屬性和方法,有可能是定義在自身键畴,也有可能是定義在它的原型對象最盅。由于原型本身也是對象,又有自己的原型起惕,所以形成了一條原型鏈(prototype chain)涡贱。
問題9:對String做擴展,實現(xiàn)如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
str.__proto__.getMostOften = function () {
var arr = this
var count = 0
var most = 0
var value
for (var i = 0; i < arr.length; i++){
for (j = 0; j < arr.length; j++){
if(arr[i] === arr[j]){
count += 1
}
}
if (count > most){
value = arr[i]
most = count
}
count = 0
}
return value
}
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現(xiàn)了5次
問題10: instanceOf有什么作用惹想?內(nèi)部邏輯是如何實現(xiàn)的问词?
instanceof 一般用于判斷一個變量是否為某個對象的實例。
查找某個變量的原型鏈上是否有某個對象的prototype嘀粱。是則返回true激挪,否則為false
繼承相關(guān)問題
問題11:繼承有什么作用?
繼承可以讓某個類型的對象獲得另一個類型的對象的屬性的方法,讓其可以使用現(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);
方法1每創(chuàng)建一個實例都會給它創(chuàng)建一個printName方法,這些實例printName方法作用相同悲柱,但是為不同的函數(shù)锋喜,會占用不同的內(nèi)存空間,造成資源的浪費;
而方法2 創(chuàng)建實例對象則只是引用prototype的方法嘿般,所有實例的sayName都是一個方法段标,不會造成資源浪費。
問題13: Object.create 有什么作用炉奴?兼容性如何逼庞?
Object.create接受一個對象作為參數(shù),然后以它為原型瞻赶,返回一個實例對象赛糟。該實例完全繼承繼承原型對象的屬性。
Object.create方法的實質(zhì)是新建一個構(gòu)造函數(shù)F砸逊,然后讓F.prototype屬性指向參數(shù)對象obj璧南,最后返回一個F的實例,從而實現(xiàn)讓該實例繼承obj的屬性师逸。
兼容性
問題14: hasOwnProperty有什么作用司倚? 如何使用?
hasOwnProperty 可以判斷某個屬性定義在對象自身篓像,還是定義在原型鏈上动知。
Date.hasOwnProperty('length')
// true
Date.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;
}
在創(chuàng)建Male實例對象時,這個this是指實例對象员辩,
call作用是讓實例對象調(diào)用Person函數(shù)實現(xiàn)繼承Person內(nèi)屬性的目的
問題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.printName = Person.prototype.getName
Male.prototype.getAge = function(){
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27)
ruoyu.printName()