1.apply、call、bind有什么作用,什么区别
apply()和call()都是调用一个函数,和第一个参数是指定的this值,区别是后面的参数,apply()方法接受的是一个包含多个参数的数组,call()方法接受若干个参数的列表
bind()方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值。
语法:
fun.apply(thisArg,[argsArray])
fun.call(thisArg,arg1,arg2,...)
fun.bind(thisArg[,arg1[,arg2[,...]]])
2.以下代码输出什么
var john = {
firstName: 'John'
}
function func(){
alert(this.firstName+":hi!");
}
john.sayHi = func;
john.sayHi()
输出结果:John:hi!
3.下面代码输出什么?为什么
func()
function func(){
alert(this)
}
输出结果:window,调用函数时,this指向全局对象,浏览器的全局对象是window
4.下面代码输出什么?
document.addEventListener('click',function(e){
console.log(this);
setTimeOut(function(){
console.log(this);
},200)
},false)
输出结果:document window
第一个this指向当前监听事件的document元素对象,setTimeOut执行函数的this指向全局对象
5.下面代码输出什么?为什么
var john = {
firstName: 'John'
}
function func(){
alert(this.firstName+":hi!");
}
func.call(john);
输出结果:John:hi!
func()函数中的this指向全局对象,在调用call()方法后将对象john作为this传入到func()函数中,func()函数的this指向john对象
6.下面代码有什么问题,如何修改
var module = {
bind: function(){
$btn.on('click',function(){
console.log(this);
this.showMsg();
})
}
showMsg: function(){
console.log('饥人谷')
}
}
事件中的this指向$btn
元素,$btn
元素没有showMsg()
函数,所以会报错,通过声明一个变量指向module对象,就可以调用showMsg()
函数了
var module = {
bind: function(){
var cur = this;
$btn.on('click',function(){
console.log(this);
cur.showMsg();
})
}
showMsg: function(){
console.log('饥人谷')
}
}
module.bind();
原型链有关的问题
7.有如下代码,解释Person、prototype、__proto__、p、constructor
之间的关联
fucntion Person(){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('my name is' + this.name);
}
var p = new Person('若愚');
p.sayName();
Person是一个构造函数,它有一个prototype对象,在prototype对象上有一个constructor属性,Person.prototype.constructor === Person
。p是Person的一个实例,拥有__proto__
属性,p.__proto__ === Person.prototype
。因此p.__proto__.constructor === Person
、p.constructor === Person
。
8.上例中,对对象p可以这样调用p.toString()
。toString
是从哪里来的,画出原型图,并解释什么是原型链
因为p.__proto__ === Person.prototype
、Person.prototype.__proto__ === Object.prototype
,toString是Object的prototype上的方法,所以p可以调用p.toString()
。
原型链:一个对象调用某个方法时,如果在该对象上不能直接找到这个方法,就通过该对象的__proto__
方法指向该对象的原型对象prototype查看是否有这个方法,如果没有就继续在prototype.__proto__
上找,直到Object.prototype.__proto__ === null
,这样一层一层向上找的链就是原型链。
9.对String
做扩展,实现如下方式获取字符串中频率最高的字符
String.prototype.getMostOften = function(){
var obj= {}, max, count = 0;
for(var i = 0; i count){
max = key;
count = obj[key];
}
}
return max;
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch);
10.instanceof
有什么作用?内部逻辑是如何实现的
instanceOf
判断一个对象是不是某个类型的实例,返回值布尔类型
内部逻辑是测试一个对象在其原型链上是否存在一个构造函数的prototype,若存在返回true,否则返回false
继承相关问题
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
有什么作用?兼容性如何?
Male.prototype = Object.create(Person.prototype);
这里通过Object.create
clone了一个新的prototype而不是直接给Person.prototype
赋值,因为引用关系,这样会导致后续修改子类的prototype也修改了父类的prototype,因为修改的是一个值。
Object.create
是ES5方法,IE9以上兼容
14.hasOwnProperty
有什么作用?如何使用?
hasOwnProperty
是Object.prototype
的一个方法,可以判断一个对象是否包含自定义属性而不是原型链上的属性,hasOwnProperty
是JavaScript中唯一一个处理属性但是不查找原型链的函数
function Person(name, sex){
this.name = name;
}
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.getAge = function(){
console.log(this.age)
};
var m= new Male('tom', '男', 2);
m.hasOwnProperty('name') //true
m.hasOwnProperty('getName') //false
Male.prototype.hasOwnProperty('getAge') //true
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;
}
call的作用是让Male继承Person的name,sex属性,this指向Male
16.补全代码,实现继承
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.getName = function(){
console.log(this.name)
};
function Male(name, sex, age){
Person.bind(this)(name,sex); //或者 Person.call(this,name,sex);
this.age = age;
}
Male.prototype = Object.create(Person.prototype);
Male.prototype.getAge = function(){
console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();