this
apply括袒、call 哆致、bind有什么作用硅蹦,什么區(qū)別?
-
apply() 方法調用一個函數, 其具有一個指定的this值,以及作為一個數組(或類似數組的對象)提供的參數昨凡。
語法:fun.apply(thisArg, [argsArray]) thisArg: 在 fun 函數運行時指定的 this 值。如果這個函數處于非嚴格模式下蚁署,則指定為 null 或 undefined 時會自動指向全局對象便脊。 argsArray: 一個數組或者類數組對象,其中的數組元素將作為單獨的參數傳給 fun 函數光戈。
call()方法和apply()方法類似哪痰,只有一個區(qū)別,計算call()方法接收若干個參數的列表田度,而apply()方法接收的是一個包含多個參數的數組妒御。
-
bind()方法創(chuàng)建一個新的函數, 當被調用時,將其this關鍵字設置為提供的值镇饺,在調用新函數時乎莉,在任何提供之前提供一個給定的參數序列。
語法:fun.bind(thisArg[, arg1[, arg2[, ...]]]) thisArg 當綁定函數被調用時奸笤,該參數會作為原函數運行時的 this 指向作儿。當使用new 操作符調用綁定函數時, 該參數無效青伤。 arg1, arg2, ... 當綁定函數被調用時潦牛,這些參數將置于實參之前傳遞給被綁定的方法。 返回值 返回由指定的this值和初始化參數改造的原函數拷貝
以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() // John: hi!
// this為執(zhí)行上下文健盒,當一個函數作為對象的方法調用時绒瘦,this默認指向這個對象
下面代碼輸出什么,為什么扣癣?
func() // [object Window]
function func() {
alert(this)
}
// 當直接調用一個函數時惰帽,相當于執(zhí)行window.func()所以this指向window對象
下面代碼輸出什么?
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
// 輸出:#document 父虑、 Window{}
// 第一個:事件中的this默認指向綁定這個事件的對象该酗。
// 第二個:setTimeout的執(zhí)行函數中的this默認指向window對象
下面代碼輸出什么,why?
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john) // Jojn
// call方法用于在函數運行時指定this指,因此執(zhí)行以上代碼時this指向john對象
以下代碼有什么問題呜魄,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指$btn對象
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
// 在事件處理函數中this指向$btn,而$btn沒有showMsg()方法
// 修改:將外部this保存到一個變量中
var module= {
bind: function(){
var self = this
$btn.on('click', function(){
console.log(this)
self.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
原型鏈
有如下代碼悔叽,解釋Person、 prototype爵嗅、proto娇澎、p、constructor之間的關聯(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(); // 'My name is: 若愚'
// Person是一個函數九火,它擁有一個prototype屬性,這個屬性指向一個對象册招,而這個對象擁有一個
constructor屬性岔激,這個屬性指向Person函數
// 當Person作為構造函數調用時,會先初始化一個對象是掰,將this指向這個對象虑鼎,并將它的__proto__屬性指
向Person.prototype,因此p.name === "若愚",p.sayName() === Person.prototype.sayName()
上例中,對對象 p可以這樣調用 p.toString()键痛。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈炫彩。
- toString來自Object.prototype。如圖:
![](http://processon.com/chart_image/59a2a6b0e4b0b17416b96541.png)
- 如上圖所示絮短,當在Person的原型找不到某個方法時江兢,就會沿著它的__proto__逐層向上,直到找到或__proto__屬性為空為止丁频,這個__proto__屬性組成的鏈杉允,就是原型鏈
對String做擴展,實現(xiàn)如下方式獲取字符串中頻率最高的字符
String.prototype.getMostOften = function() {
var obj = {}
var strArr = this.split('')
strArr.forEach(function(i) {
if (obj[i]) {
obj[i]++
} else {
obj[i] = 1
}
})
var max = 0, maxStr
for (var x in obj) {
if (obj[x] > max) {
maxStr = x
max = obj[x]
}
}
return maxStr
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d
instanceOf有什么作用席里?內部邏輯是如何實現(xiàn)的叔磷?
- instanceof用于判斷一個對象的類型,那么它的判斷規(guī)則是什么奖磁?
- Instanceof運算符的第一個變量一般是一個對象改基,暫時稱為A;第二個變量一般是一個函數咖为,暫時稱為B秕狰。
- Instanceof的判斷規(guī)則是:沿著A的__proto__這條線來找,同時沿著B的prototype這條線來找躁染,如果兩條線能找到同一個引用封恰,即同一個對象,那么就返回true褐啡。如果找到終點還未重合,則返回false鳖昌。
繼承
繼承有什么作用?
- 繼承關系是傳遞的备畦。若類C繼承類B低飒,類B繼承類A,則類C既有從類B那里繼承下來的屬性與方法懂盐,也有從類A那里繼承下來的屬性與方法褥赊,還可以有自己新定義的屬性和方法。繼承來的屬性和方法盡管是隱式的莉恼,但仍是類C的屬性和方法拌喉。繼承是在一些比較一般的類的基礎上構造、建立和擴充新類的最有效的手段俐银。
- 繼承提供了軟件復用功能尿背。若類B繼承類A,那么建立類B時只需要再描述與基類(類A)不同的少量特征(數據成員和成員方法)即可捶惜。這種做法能減小代碼和數據的冗余度田藐,大大增加程序的重用性。
- 繼承通過增強一致性來減少模塊間的接口和界面吱七,大大增加了程序的易維護性汽久。
下面兩種寫法有什么區(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ū)別:使用方法1構造的每個對象都擁有相同的printName方法,
使用方法2構造的每個對象調用printName方法時都是調用的Person.prototype.printName方法
方法2大大節(jié)省了內存
Object.create 有什么作用踊餐?兼容性如何景醇?
-
Object.create() 方法會使用指定的原型對象及其屬性去創(chuàng)建一個新的對象。兼容ie9及以上瀏覽器
var p1 = Object.create(xxx.prototype) 相當于: var fn = {} fn.__proto__ = xxx.prototype var p1 = fn
hasOwnProperty有什么作用吝岭? 如何使用三痰?
-
hasOwnProperty() 方法會返回一個布爾值,指示對象是否具有指定的屬性作為自身(不繼承)屬性苍碟。
遍歷一個對象所有自身屬性: var buz = { fog: 'stack' }; for (var name in buz) { if (buz.hasOwnProperty(name)) { alert("this is fog (" + name + ") for sure. Value: " + buz[name]); } }
如下代碼中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex);
//調用Person函數酒觅,并把它的this變?yōu)镸ale函數的this,用此方法可實現(xiàn)對Person實例屬性的繼承
this.age = age;
}
補全代碼微峰,實現(xiàn)繼承
function Person(name, sex){
this.name = name
this.sex = sex
}
Person.prototype.printName = 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.printName();