校招前端面试题100道(3)

二十一.继承方法

JS实现继承的几种方式:

1、属性拷贝(混入式继承)

	特点:如果属性的值是引用类型的数据, 子对象和父对象共享同一份数据, 修改其中一个会影响另一个
 var obj = {name : 'zs',age : 20,friends:['小明','小红']};
 var  obj1 = {}; // 需求:obj1获取obj的属性
 for(var key in obj){
      obj1[key] = obj[key];
  }
  obj1.friends.push('老王');// 修改了obj1的friends对obj的friends会有影响,因为他们存储的是同一个数组的地址
  console.log(obj1);
  console.log(obj);

2、原型式继承

Son.prototype = Father.prototype(父构造函数的原型对象赋值给子构造函数的原型对象)

创建出来的对象, 构造器属性, 默认指向父构造函数
无法通过构造器属性进行修改
不能获取实例属性/方法, 只能获取父构造函数原型对象的属性和方法
// 创建父构造函数
function SuperClass(name){
  this.name = name;
  this.showName = function(){
    alert(this.name);
  }
}
// 设置父构造器的原型对象
SuperClass.prototype.showAge = function(){
  console.log(this.age);
}
// 创建子构造函数
function SubClass(){
}
// 设置子构造函数的原型对象实现继承
SubClass.prototype = SuperClass.prototype;(关键在这里!!!!!)
var child = new SubClass()

3、原型链继承
子构造函数.prototype = new 父构造函数()

无法传递参数给父构造函数-13
继承过来的实例属性会成为原型属性, 
对创建出来的对象存在数据共享的问题
// 创建父构造函数
function SuperClass(){
    this.name = 'liyajie';
    this.age = 25;
    this.showName = function(){
        console.log(this.name);
    }
}
// 设置父构造函数的原型
SuperClass.prototype.friends = ['小名', '小强'];
SuperClass.prototype.showAge = function(){
    console.log(this.age);
}
// 创建子构造函数
function SubClass(){

}
// 实现继承
SubClass.prototype = new SuperClass();
// 修改子构造函数的原型的构造器属性
SubClass.prototype.constructor = SubClass;

var child = new SubClass();
console.log(child.name); // liyajie
console.log(child.age);// 25
child.showName();// liyajie
child.showAge();// 25
console.log(child.friends); // ['小名','小强']

// 当我们改变friends的时候, 父构造函数的原型对象的也会变化
child.friends.push('小王八');
console.log(child.friends);["小名", "小强", "小王八"]
var father = new SuperClass();
console.log(father.friends);["小名", "小强", "小王八"]

4、借用构造函数继承
使用call和apply借用其他构造函数的成员

 可以解决给父构造函数传递参数的问题, 但是获取不到父构造函数原型上的成员.
 也不存在共享问题
 只能获取实例属性和方法, 不能获取原型属性和方法
// 创建父构造函数
function Person(name){
  this.name = name;
  this.freinds = ['小王', '小强'];
  this.showName = function(){
     console.log(this.name);
  }
}
// 创建子构造函数
 function Student(name){
  // 使用call借用Person的构造函数
  Person.call(this, name);
 }
 // 测试是否有了 Person 的成员
 var stu = new Student('Li');
 stu.showName(); // Li
 console.log(stu.friends); // ['小王','小强']

5、组合继承
借用构造函数 + 原型式继承

解决了 父构造函数的属性继承到了子构造函数的实例对象上了,
继承了父构造函数原型对象上的成员
解决了给父构造函数传递参数问题
// 创建父构造函数
function Person(name,age){
    this.name = name;
    this.age = age;
    this.showName = function(){
        console.log(this.name);
    }
}
// 设置父构造函数的原型对象
Person.prototype.showAge = function(){
    console.log(this.age);
}
// 创建子构造函数
function Student(name){
    Person.call(this,name);
}
// 设置继承
Student.prototype = Person.prototype;
Student.prototype.constructor = Student;

6、 借用构造函数 + 深拷贝

	这样就将Person的原型对象上的成员拷贝到了Student的原型上了, 
	这种方式没有属性共享的问题
function Person(name,age){
    this.name = name;
    this.age = age;
    this.showName = function(){
        console.log(this.name);
    }
}
Person.prototype.friends = ['小王','小强','小王八'];
function Student(name,25){	   
    Person.call(this,name,25); // 借用构造函数(Person)
}
deepCopy(Student.prototype,Person.prototype);// 使用深拷贝实现继承
Student.prototype.constructor = Student;

二十二.团队合作的经验
二十三.通宵经历(不是玩的)
二十四.课外项目(自己瞎做的那种)
二十五.为什么学前端?
二十六.有没有参赛或者除了学校课程内容外的经验?应该是想知道有没有合作经验

二十七.原型与原型链

在这里插入图片描述
原型:

①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
③所有引用类型的__proto__属性指向它构造函数的prototype

原型链:

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,
如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,
如果还没有找到就会再在构造函数的prototype的__proto__中查找,
这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

拓展:js中的数据类型有以下几种:

Number   Boolean   undefined     Object   Function    String  Null

基本类型:Number Boolean  String  undefined null

引用类型:Object  Function

二十八.辗转相除法

辗转相除法又名欧几里得算法,目的是求出两个正整数的最大公约数。

function remainder(m,n){		
		var r = 0;//定义变量存储余数
		while (m % n != 0){
			r = m % n;
			m = n;//把除数 n 当做下一轮的被除数
			n = r;//把余数 r 当做下一轮的除数
		}
        //当余数为0时,最后一个除数就是所求的最大公约数
		return n;		
}
console.log(remainder(350,505));

二十九.数组转字符串

toString()	将数组转换成一个字符串(var s = a.toString();)
toLocalString()	把数组转换成本地约定的字符串(var s = a.toLocalString();)
join()	将数组元素连接起来以构建一个字符串(var s = a.join("==");)

拓展:

 split() 方法把字符串转换为数组。
 split() 方法是 String 对象方法,与 join() 方法操作正好相反。(var a = s.split("==");)

三十.二级下拉菜单

Js:

 window.onload=function(){
  var aLi=document.getElementById("nav").getElementsByTagName("li"); 
    for(var i=0; i<aLi.length;i++){                
        aLi[i].onmouseover=function(){
            this.children[1].style.display='block';//选取当前li元素的第二个子元素
        }
        aLi[i].onmouseout=function(){
            this.children[1].style.display='none';
        }
    }
}

Jq:

$(function(){
  $(".banner>ul>li").mouseenter(function(){
         $(this).find("ul").css("display","block");
     });
     // 给div下的一级菜单li注册事件,鼠标进入显示该li下的二级菜单的ul
     $(".banner>ul>li").mouseleave(function(){
         $(this).find("ul").css("display","none");
     });
     // 给div下的一级菜单li注册事件,鼠标离开隐藏该li下的二级菜单的ul

 });

拓展更多面试题(100道前端面试题练手):

1、前端近年面试题(1)
2、前端近年面试题(2)
3、前端近年面试题(3)
4、前端近年面试题(4)
5、前端近年面试题(5)
6、前端近年面试题(6)
7、前端近年面试题(7)
8、前端近年面试题(8)
9、前端近年面试题(9)

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值