問題1: apply、call 、bind有什么作用,什么區別
- function.prototype.bind()方法用于將函數體內的this綁定到某個對象,然后返回一個新函數。
function Count() {
this.count = 1
}
Count.prototype.doing = function () {
console.log(this.count + 100)
}
var obj = {
count: 200
}
var a = new Count().doing.bind(obj)//把obj的this綁定到bind()函數上,也就是doing函數
console.log(a())
- function.prototype.call()
函數實例的call方法,可以指定函數內部this的指向(即函數執行時所在的作用域),然后在所指定的作用域中,調用該函數。
var obj = {}
var a = function() {
console.log(this)
}
a()//指向window
a.call(obj)//指向obj
var b = Math.max.call(null,1,3,5,7,3,11)//輸出11
- function.prototype.apply()
apply方法的作用與call方法類似,也是改變this指向,然后再調用該函數。唯一的區別就是,它接收一個數組作為函數執行時的參數
var c = Math.max.apply(null,[1,3,5,7,3,11])//輸出11
問題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] 由于函數名提升,所以不會是undefined,函數內部的this指向全局window
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);//#document
setTimeout(function(){
console.log(this);//window
}, 200);
}, false);
問題5:下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)//輸出john,call把func函數執行的作用域call到john對象上
問題6: 以下代碼有什么問題,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么,這里的this指向$btn
this.showMsg();
}.bind(module))//這里加一個bind,把函數作用域bind到module即可
},
showMsg: function(){
console.log('饑人谷');
}
}
原型鏈相關問題
問題7:有如下代碼,解釋Person、 prototype、proto、p、constructor之間的關聯。
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();
p instanceof Person === true
//p是原型Person的一個實例,擁有Person原型鏈上的屬性和方法
p.__proto__ === Person.prototype
Person.prototype.constructor === p.__proto__.constructor
問題8: 上例中,對對象 p可以這樣調用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
image.png
- p先在自身找toString沒有找到,然后去p.proto找還是沒有找到,又去p.proto.proto里面找,然后找到。
- 每個對象都有一個私有屬性(稱之為 [[Prototype]]),它持有一個連接到另一個稱為其 prototype 對象(原型對象)的鏈接。該 prototype 對象又具有一個自己的原型,層層向上直到一個對象的原型為 null。
問題9:對String做擴展,實現如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
String.prototype.getMostOften = function () {
var strArr = [].slice.apply(this)
var obj = {}
var maxTimes = 0
var valueOfMaxTimes
strArr.forEach(function (letter, idx) {
if (obj[letter]) {
obj[letter] += 1
} else {
obj[letter] = 1
}
});
console.log(obj)
for (var key in obj) {
console.log(key)
if (obj[key] >= maxTimes) {
maxTimes = obj[key]
valueOfMaxTimes = key
} else {
return '出現次數最多的字母是:' + valueOfMaxTimes + '\n' + '出現次數最多的字母的次數是:' + maxTimes + '次'
}
}
}
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現了5次
instanceOf有什么作用?內部邏輯是如何實現的?
- instanceof運算符返回一個布爾值,表示指定對象是否為某個構造函數的實例
*由于instanceof對整個原型鏈上的對象都有效,因此同一個實例對象,可能會對多個構造函數都返回true。
var d = new Date();
d instanceof Date // true
d instanceof Object // true
繼承相關問題
問題11:繼承有什么作用?
- 子類可以擁有父類的屬性和方法,避免重復,簡化代碼,有利于維護。可以使用另一個對象的屬性和方法在原對象的基礎上擴展屬性和方法,而不影響原對象。
問題12: 下面兩種寫法有什么區別
//方法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 方法,方法2每次創建實例會共享一個printName 方法,不會再次去創建
問題13: Object.create 有什么作用?兼容性如何?
- Object.create() 方法會使用指定的原型對象及其屬性去創建一個新的對象。
- 兼容性:Object.create是ES5方法,IE9以下無效
- 用 Object.create實現類式繼承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
console.log(this.name)
}
function Male(name,age,sex) {
this.sex = sex
Person.apply(this,arguments)//使用apply方法技術Person屬性
}
Male.prototype = Object.create(Person.prototype)//使用Object.create()方法繼承Person的方法
Male.prototype.constructor = Male
var man = new Male('Jack',18,'男')
man.sayName()
問題14: hasOwnProperty有什么作用? 如何使用?
*對象實例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。
- hasOwnProperty方法是JavaScript之中唯一一個處理對象屬性時,不會遍歷原型鏈的方法。
Math.hasOwnProperty('min')
//true
Math.hasOwnProperty('abs')
//true
Math.hasOwnProperty('toString')
問題15:如下代碼中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //這里的 call把person的作用域改為Male
this.age = age;
}
問題16:補全代碼,實現繼承
function Person(name, sex) {
this.name = name
this.sex = sex
}
Person.prototype.getName = function () {
console.log('姓名:' + this.name)
};
function Male(name, sex, age) {
this.age = age
Person.apply(this, arguments)
}
Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male
Male.prototype.getAge = function() {
console.log(this.age)
}
var ruoyu = new Male('若愚', '男', 27);
ruoyu.getAge();