this 相關(guān)問(wèn)題
問(wèn)題1: apply梆暖、call 伞访、bind有什么作用,什么區(qū)別
作用: 給函數(shù)指定this轰驳。是用來(lái)指定上下文的
區(qū)別: bind:bind()會(huì)創(chuàng)建一個(gè)新的函數(shù)厚掷,將其中的值,作為原來(lái)函數(shù)的this级解。例如xx.bind(obj)中冒黑,obj為xx的this 。將函數(shù)體中的this綁定到對(duì)象上勤哗,然后返回一個(gè)新的函數(shù)抡爹。
call: call()是使用一個(gè)指定的this值和相關(guān)參數(shù)的前提下調(diào)用函數(shù)或方法。接受的參數(shù)為若干個(gè)參數(shù)的列表芒划。簡(jiǎn)單來(lái)說(shuō)冬竟,就是可以指定函數(shù)內(nèi)部this的指向(即在此函數(shù)執(zhí)行時(shí)所在的作用域),讓在所指定的作用域中民逼,調(diào)用該函數(shù)泵殴。就是var obj={};function fn(){ return this;};fn.call(obj),call改變this的指向拼苍。讓fn的this是指向obj的笑诅,在obj的作用域中運(yùn)行
apply: apply()效果同call(),不過(guò)其接受的參數(shù)為數(shù)組疮鲫。
問(wèn)題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() ==》方法調(diào)用
輸出:
john hi!
問(wèn)題3: 下面代碼輸出什么吆你,為什么
func()
function func() {
alert(this)
} ==》函數(shù)調(diào)用
輸出: window,因?yàn)樵趂unction中的this俊犯,沒(méi)有找到對(duì)象早处,所以繼續(xù)向外找,
而function的外部環(huán)境為window瘫析,則輸出window
問(wèn)題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
輸出:document
window
問(wèn)題5:下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
輸出:john
原因:call()函數(shù)為func函數(shù)綁定了this=john
call()函數(shù)將func函數(shù)的this指向了john默责,并且func的執(zhí)行在john的作用域中
問(wèn)題6: 以下代碼有什么問(wèn)題贬循,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
問(wèn)題:console.log出來(lái)的是$btn 饑人谷 ;//不知道桃序。
當(dāng)調(diào)用module.bind()的時(shí)候杖虾。this.showMsg()無(wú)法調(diào)用。因?yàn)檫@里的this指向了$btn媒熊。所以將this.showMsg()改為module.showMsg()奇适;
或是通過(guò)嫁接方式坟比;var that=this;that.showMsg();
原型鏈相關(guān)問(wèn)題
問(wè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();
關(guān)聯(lián):p是Person的構(gòu)造對(duì)象,而Person是構(gòu)造函數(shù)贷祈。 在new的過(guò)程中趋急,p的-proto-指向 Person,因?yàn)镻erson的原型上綁定一個(gè)方法:sayName势誊,即constructor下有sayName呜达。所以p 擁有屬性:name;和方法sayName()粟耻。
問(wèn)題8: 上例中查近,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()。toString是哪里來(lái)的? 畫(huà)出原型圖?并解釋什么是原型鏈勋颖。
來(lái)自上一級(jí)的原型嗦嗡。
https://www.draw.io/#Hkomolei%2Ftry%2Fmaster%2FUntitled%20Diagram.xml
原型鏈:所有的對(duì)象都有-proto-這個(gè)屬性,這個(gè)鏈接到另一個(gè)-proto-饭玲,像這樣一個(gè)個(gè)-proto-相鏈接起來(lái)的樣子侥祭,稱(chēng)為原型鏈。對(duì)于函數(shù)茄厘,則是prototype了矮冬。
問(wèn)題9:對(duì)String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
String.prototype.getMostOften =
function () {
// var str = 'ahbbccdeddddfg';
var str=this;
// console.log(this);
var o = {};
for (var i = 0; i < str.length; i++) {
var char = str.charAt(i);
if (o[char]) {
o[char]++; //次數(shù)加1
} else {
o[char] = 1; //若第一次出現(xiàn)次哈,次數(shù)記為1
}
}
// console.log(o); //輸出的是完整的對(duì)象胎署,記錄著每一個(gè)字符及其出現(xiàn)的次數(shù)
//遍歷對(duì)象,找到出現(xiàn)次數(shù)最多的字符的次數(shù)
var max = 0;
for (var key in o) {
if (max < o[key]) {
max = o[key]; //max始終儲(chǔ)存次數(shù)最大的那個(gè)
}
}
for (var key in o) {
if (o[key] == max) {
//console.log(key);
// console.log("最多的字符是" + key);
// console.log("出現(xiàn)的次數(shù)是" + max);
return key;
}
}
}
var ch = str.getMostOften();
console.log(ch);
問(wèn)題10: instanceOf有什么作用窑滞??jī)?nèi)部邏輯是如何實(shí)現(xiàn)的琼牧?
作用: instanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性。
就是檢測(cè)一個(gè)原型鏈上是否存在某個(gè)prototype哀卫。a.instanceof b.prototype :就是a的原型鏈中是否存在b.prototype;
實(shí)現(xiàn)邏輯:讓其一層一層沿著原型鏈去查找巨坊,找到就return true;
繼承相關(guān)問(wèn)題
問(wèn)題11:繼承有什么作用?
繼承:一個(gè)對(duì)象繼承另一個(gè)對(duì)象的所有的屬性和方法〈烁模可以得到另一個(gè)對(duì)象的屬性和方法趾撵。
問(wèn)題12: 下面兩種寫(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ū)別:方法1是 綁定在People上。方法2的printName是綁定到原型上共啃。在new多個(gè)實(shí)例的時(shí)候占调,方法2可以直接調(diào)用暂题。在多次調(diào)用的時(shí)候可以?xún)?yōu)化內(nèi)存空間。而方法1要多次寫(xiě)入究珊。
同時(shí)方法2中要更改prototype的時(shí)候薪者,其的每一個(gè)實(shí)例的printName都會(huì)改變。而方法1需要每個(gè)都是修改苦银。
問(wèn)題13: Object.create 有什么作用啸胧?兼容性如何?
Object.create() 方法使用指定的原型對(duì)象和其屬性創(chuàng)建了一個(gè)新的對(duì)象幔虏。簡(jiǎn)單來(lái)說(shuō)就是可以手動(dòng)的去指定對(duì)象的原型纺念。創(chuàng)建一個(gè)新的對(duì)象,第一層的原型鏈指向?qū)?yīng)的參數(shù)想括。
兼容性:支持各個(gè)瀏覽器陷谱。ie需要ie9以上。
問(wèn)題14: hasOwnProperty有什么作用瑟蜈? 如何使用烟逊?
作用:看對(duì)象上的屬性是屬于自己的,還是從原型鏈繼承來(lái)的铺根。
使用:object.hasOwnPrototype(" 屬性")
問(wèn)題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繼承Person中的屬性宪躯。手動(dòng)將this指向Person。就是將Person中的this引用到Male中位迂。
問(wèn)題16: 補(bǔ)全代碼访雪,實(shí)現(xiàn)繼承
function Person(name, sex){
// todo ...
this.name=name;
this.sex=sex;
}
Person.prototype.getName = function(){
// todo ...
console.log(this.name);
};
function Male(name, sex, age){
//todo ...
Person.call(this,name,sex)
this.age=age;
//this.printName=function(){
// console.log(this.name)
//}
this.printName=Person.prototype.getName;
}
//todo ...
Male.prototype.getAge = function(){
//todo ...
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
或是:
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;
//this.printName=function(){
// console.log(this.name)
//}
//this.printName=Person.prototype.getName;
}
//todo ...
Male.prototype=new Person() ; //繼承:將一個(gè)對(duì)象的prototype指向要繼承的對(duì)象即可
Male.prototype.getAge = function(){
// todo ...
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();