問題1: apply胀溺、call 矾屯、bind有什么作用,什么區(qū)別
- bind
返回一個(gè)新函數(shù)惰赋,并且使函數(shù)內(nèi)部的 this 為傳入的第一個(gè)參數(shù)
- call
調(diào)用一個(gè)函數(shù)详恼,為其指定 this , 分別提供參數(shù)
- apply
調(diào)用一個(gè)函數(shù)房午,為其指定 this 墓赴,參數(shù)以數(shù)組形式傳入
var value = 2;
function sum(a, b) {
console.log( this.value + a + b )
//return this.value + a +b
}
//直接調(diào)用
sum(5,6) // 2+5+6 =13
//apply 指定this ,參數(shù)以數(shù)組的形式傳遞
var obj1 = {
value: 3
}
sum.apply(obj1, [5, 6]) // 3+5+6
//call 指定 this 渗钉,分別提供參數(shù)
var obj2 = {
value: 1
}
sum.call(obj2, 5, 6) // 2+5+6
//bind 指定 this 彤恶,返回一個(gè)新的函數(shù)
var obj3 = {
value: 7
}
var newSum = sum.bind(obj3)
newSum(5,6) // 7+5+6
問題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
輸出結(jié)果 John:hi! 因?yàn)檫@里的sayHi 是 john 調(diào)用的,所以 this 指向
join 對(duì)象
問題3: 下面代碼輸出什么鳄橘,為什么
func()
function func() {
alert(this)
}
在瀏覽器運(yùn)行時(shí)声离, this 是指window ,因此瘫怜,代碼運(yùn)行后术徊,會(huì)彈窗顯示 window 對(duì)象。
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
第一個(gè) this
是指 document
鲸湃, 因?yàn)槭录壎ㄗ詣?dòng)把this
指向?qū)?yīng)元素赠涮。第二個(gè) this
為 window
,因?yàn)槟涿瘮?shù)的執(zhí)行是在window
全局下的
問題5:下面代碼輸出什么唤锉,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
彈窗顯示 Jonhn
,因?yàn)?code>call 指定this
為john
對(duì)象别瞭。
問題6: 以下代碼有什么問題窿祥,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) // this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
this
指調(diào)用事件的 DOM 元素,要想讓 this
指向?qū)ο蟊旧眚梢员4嬖瓉淼?code>this
var module= {
bind: function(){
var _this = this
$btn.on('click', function(){
console.log(self)
self.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
是構(gòu)造函數(shù)靠胜, prototype
是構(gòu)造函數(shù)的共有屬性。 p
是Person
的實(shí)例,該實(shí)例有__proto__
對(duì)象指向Person.prototype
浪漠。constructor
表示該實(shí)例的構(gòu)造器陕习,指向Person
。
p.__proto__.constructor === Person.prototype.constructor === Person
問題8: 上例中址愿,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()该镣。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
p.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.protyotype
toString
是Object的prototype上的方法响谓,所以p
可以調(diào)用p.toString()
問題9:對(duì)String做擴(kuò)展损合,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因?yàn)閐 出現(xiàn)了5次
String.prototype.getMostOften = function(){
var arr = {};
// 找到字符串里所有字母他的個(gè)數(shù)保存至對(duì)象 arr。
for(i=0; i<this.length; i++){
if (arr[ this[i] ]){
arr[ this[i] ]++;
}else {
arr[ this[i] ] = 1;
}
}
var max = 0, maxStr;
// 遍歷對(duì)象 arr 把出現(xiàn)次數(shù)最大值賦值給 max;
for(var key in arr){
if (arr[key] > max){
max = arr[key];
maxStr = key;
}
}
return maxStr + "娘纷,因?yàn)?" + maxStr + " 出現(xiàn)了" + max + "次";
};
問題10: instanceOf有什么作用嫁审??jī)?nèi)部邏輯是如何實(shí)現(xiàn)的?
instanceOf用來判斷一個(gè)對(duì)象是是否是一個(gè)構(gòu)造函數(shù)的實(shí)例失驶。內(nèi)部是通過判斷instance.__proto__ === Object.prototype
是否相同來實(shí)現(xiàn)的土居,假如當(dāng)前不相等,就會(huì)根據(jù)原型鏈往上找嬉探,instance.__proto__.__proto__ === Object.prototype
擦耀,直到null,找到就返回true涩堤,否則為false眷蜓。
問題11:繼承有什么作用?
繼承是面向?qū)ο缶幊痰囊粋€(gè)特點(diǎn)之一,一個(gè)對(duì)象可以使用另一個(gè)對(duì)象的屬性和方法胎围。它劃分了類的層次吁系,父類代表的是更一般、更泛化的類白魂,而子類則是更為具體汽纤、更為細(xì)化。
繼承是實(shí)現(xiàn)代碼重用福荸、擴(kuò)展軟件功能的重要手段蕴坪,子類中與父類完全相同的屬性和方法不必重寫,只需寫出新增或改寫的內(nèi)容敬锐,這就是說子類可以復(fù)用父類的內(nèi)容背传,不必一切從零開始。
問題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);
方法一:將printName
作為對(duì)象的自有方法定義台夺,對(duì)象實(shí)例化后自身?yè)碛羞@個(gè)方法径玖,每次new
出來實(shí)例,都會(huì)產(chǎn)生新的屬性和方法颤介,占用過多不必要的內(nèi)存梳星。
方法二: 將printName
放在構(gòu)造方法的prototype
屬性中赞赖,實(shí)例化對(duì)象可以通過原型鏈查找調(diào)用這個(gè)方法使用原型的好處可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法。每次new
出來的實(shí)例丰泊,會(huì)產(chǎn)生新的屬性薯定,但方法都在共有的屬性原型鏈(prototype)上,節(jié)省內(nèi)存瞳购。
問題13: Object.create 有什么作用话侄?兼容性如何?
Object.create()
方法會(huì)使用指定的原型對(duì)象及其屬性去創(chuàng)建一個(gè)新的對(duì)象学赛,實(shí)現(xiàn)繼承年堆。
Student.prototype = Object.create(Person.prototype);
問題14: hasOwnProperty有什么作用? 如何使用盏浇?
hasOwnProperty()
方法返回一個(gè)布爾值变丧,指示對(duì)象自身屬性中是否具有指定的屬性(是自身屬性,不包含prototype
)绢掰。
function Person(){
this.name = 'jack'
}
Person.prototype.commonName = 'Person'
var a = new Person()
console.log(a.hasOwnProperty('name'))
問題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;
}
作用是將Person
中的this
作用域指向Male
痒蓬,實(shí)現(xiàn)構(gòu)造函數(shù)繼承
問題16: 補(bǔ)全代碼,實(shí)現(xiàn)繼承
function Person(name, sex) {
this.name = name
this.sex = sex
}
Person.prototype.printName = function() {
console.log('My name is '+ 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(){
return this.age
}
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();