Part1:this
1.apply、call 有什么作用,什么区别
apply和call的作用是给function函数去指定this和参数;
apply语法:func.apply(thisValue, [arg1, arg2, ...]);
call语法:func.call(thisValue, arg1, arg2, ...)
this.value
在func运行时指定的this值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值
,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),
同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
apply和call的区别:
apply函数的语法与call的语法几乎完全相同,唯一的区别在于,call方法接受的是一个参数列表,而apply方法接受的是一个包含多个参数的数组(或类数组对象)
2. 以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
//输出John: hi!
this指向对象john
3.下面代码输出什么,为什么
func()
function func() {
alert(this)
}
输出为[Object window],.//因为func函数在全局对象中运行
4.下面代码输出什么
document.addEventListener('click', function(e){
console.log(this);//document,在事件处理程序中,this代表事件源的DOM对象
setTimeout(function(){
console.log(this);//window ,setTimeout和setInterval这两个方法执行
的函数指向全局对象
}, 200);
}, false);
5.下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
输出:Jhon,因为使用call这个方法将func的this绑定在john这个对象上
6.以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指$btn这个DOM对象,因此此时的this不在指向module,所有找不到
showMsg这个方法
this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
-----------------------------------------------------
修改:
var module= {
bind: function(){
var _this = this;
$btn.on('click', function(){
console.log(this) //$btn
_this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
Part2:原型链
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();
Person是一个构造函数,也是一个 对象,这个对象里存在一个prototype属性,而构造函数内部定义了一些属性和方法,这些属性和方法是属于该类的所有实例的特征;
prototype是一个构造函数的原型对象,其拥有constructor和proto属性,而constructor这个属性是指向构造函数Person,而proto指向该对象的原型;
p是通过构造函数Person构造出来的实例,也是拥有proto属性。所以p.proto === Person.prototype;
8.上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
p调用toString()时,首先会从自己查看toString()这个方法,如果没有则会沿着proto这个属性进入Person的prototype里面查看,如果还是没有找到toString()这个方法,会沿着prototype.proto的属性去到Object的prototype里查看,最后找到toString(),然后调用。
原型链:由于原型对象本身也是对象,而每个javascript对象都有一个原型对象,每个对象都有一个隐藏的proto属性,原型对象也有自己的原型,而它自己的原型对象又可以有自己的原型,这样就组成了一条链,这个就是原型链。在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined。原型链一般实现为一个链表,这样就可以按照一定的顺序来查找。
9.对String做扩展,实现如下方式获取字符串中频率最高的字符
String.prototype.getMostOften = function(){
var obj = {},
most = 0,
which;
for(var i=0 ,str; i<this.length;i++){
str = this[i];
if(obj[str]){
obj[str] += 1;
}else{
obj[str] = 1;
}
}
for(var key in obj){
if(obj[key] > most){
most = obj[key];
which = key;
}
}
return which;
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
10. instanceOf有什么作用?内部逻辑是如何实现的?
instanceOf的作用是用来判断对象是否是另一个的对象的实例,并返回布尔值。
Object.prototype.instaceOf = function(obj1,obj2){
var obj1 = obj1.__proto__;
while(obj1.__proto__){
if(obj1 === obj2.prototype){
return true;
}else{
obj1 = obj1.__proto__;
}
return 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);
区别:
方法一将printName方法定义在构造函数People内,如果构建的对象比较多,代码就会很多,对性能造成负面影响;
方法二将printNmae方法定义在Person的原型对象内,这样构建出来的对象,即使内部没有定义,还是能够通过原型链得到此方法,节约了内存。这种方法比较先进。
13.Object.create 有什么作用?兼容性如何?
Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。Object.create是在ES5中规定的,IE9以下无效。
14 hasOwnProperty有什么作用? 如何使用?
hasOwnPerperty
是Object.prototype
的一个方法,可以判断一个对象是否包含自定义属性而不是原型链上的属性,hasOwnProperty
是JavaScript中唯一一个处理属性但是不查找原型链的函数。
用法
obj.hasOwnPerperty('key') // true or false;
ex:
Person.hasOwnPerperty('name')//true;
15.如下代码中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); ////调用Person函数,使Male函数能够执行Person上的初始化代码,实现构造函数继承,
并且使Person执行时的this指向Male;
this.age = age;
}
16.补全代码,实现继承
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(name, sex, age){
Person.apply(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();
感谢瓜子观众!!!-。-