1.原型链分析图:
该分析图是个人通过学习而得出的结论;
该图是通过网上查询得到的结论
原型链:原型形成的一条链,js在查找的过程中,如果自有属性和方法中找不到,就会去原型方法中
找,如果原型对象中还查不到,就回去原型对象中的原型中查找;直到查找到原型链的顶端---Object;
2.创建一个人类然后继承学生类以及教师类,分别通过三种不同的继承方式,总结优点缺点
(1)原型链继承:
优点:实例的构造函数的属性,父类构造函数属性,父类原型的属性
缺点:新实例无法向父类构造函数传参。继承单一(无法初始化对应的属性,只有在继承的时候设置了一次)
<script>
//人类(构造函数)
function People(name,age,gender){
this.name=name;
this.age=age;
this.gender;
}
People.prototype.talk=function(){
console.log(this.name+"正在讨论")
}
People.prototype.study=function(){
console.log(this.name+"正在学习")
}
//教师:构造函数 继承 人类People中所有的属性和方法
//原型链继承:将原型改成对应的对象
//构造函数里没有就会去原型上找
//缺点:无法初始化对应的属性,只有在继承的时候设置了一次
function Teacher(name,age,color){
}
//将people挂载到teacher原型上
Teacher.prototype=new People("语文老师",34,"女");
Teacher.prototype.watch=function(){
console.log('窗前明月光')
}
var s1=new Teacher("英语老师",24,"女");
console.log(s1);
console.log(s1.name); // 输出 语文老师
</script>
(2)冒充继承法:
优点:解决了原型链继承缺点;可以继承多个构造函数属性(call多个)
缺点:无法将原型同时继承过来
//人类(构造函数)
function People(name,age,gender){
this.name=name;
this.age=age;
this.gender; // people 里面this指向window
}
People.prototype.talk=function(){
console.log(this.name+"正在讨论")
}
People.prototype.study=function(){
console.log(this.name+"正在学习")
}
function student(name,age,color){
this.name = "李四";
// People(name,age,gender) // people 里面this指向window,this指向问题
//由于people指向问题 我们可以改变people的指向性
// 在js改变this的指向性的方法 call和apply方法
People.call(this,name,age,color)
}
student.prototype.watch=function(){
console.log('我是一个学生在看视频')
}
var s2=new student("小红",24,"女");
console.log(s2); //拿不到原型上的方法
</script>
(2)组合继承法(原型链继承+冒充继承)
优点:可以继承父类原型上的属性,可以传参,可复用;每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
//人类(构造函数)
function People(name,age,gender){
this.name=name;
this.age=age;
this.gender; // people 里面this指向window
}
People.prototype.talk=function(){
console.log(this.name+"正在讨论")
}
People.prototype.study=function(){
console.log(this.name+"正在学习")
}
function student1(name,age,color){
People.call(this,name,age,color)
}
// 我们将原型也继承过来
student1.prototype = new People() //按照原型链找对应的方法
student1.prototype.listen=function(){
console.log('我是一个学生在听音乐')
}
var a1 = new student1("李华",23,"男");
console.log(a1);
console.log(a1.name); //输出大华
a1.talk() // 输出大华正在讨论
</script>
3.整理call(),apply() 使用方式 举例 以及 区别 Math.max Math.min?
call(),apply() 主要作用都是改变this指向的;两者传递参数上不同。
call() ---> .call(对象,参数,参数2,参数3) ,参数之间是用逗号隔开
apply() ---> .apply(对象,[ ]) ,对象 传递时传的是数组
<script>
function Student(name){
this.name=name
this.showName=function(){
console.log(this.name)
}
this.abc=function(a,b,c){
console.log(this.name+a+b+c)
}
}
var s1 = new Student("张三");
var s2 = new Student("李四");
s1.showName(); //此时会输出 --> 张三
//此时我们可以用call()方法改变this的指向
s1.showName.call(s2); //此时会输出李四
s1.abc.call(s2,1,2,3);
//而 appl()方法实现也是一样,只是传递参数时不同
// apply() 传递参数时 传的是数组 Array[]
var arr=[1,2,3]
s1.abc(arr[0],arr[1],arr[2])
s1.abc.apply(s1,arr)
s1.abc.apply(s2,[1,2,3])
</script>
Math.max 与 Math.min 区别:
两个方法用来获取给定的一组数值中的最大值或最小值,但是却不接受数组作为参数。
Math.max :
获取数组中的最大值;
Math.min :
获取数组中的最小值;
<script>
var arr=[70,80,60,44,55]
var result1=Math.max.apply(null,arr);
var result2=Math.min.apply(null,arr);
console.log(result1); // 80 -- 最大值
console.log(result2); // 44 -- 最小值
</script>
执行结果:
4.面向对象 set get 作用以及目的 如何实现私有属性
<script>
function user(name,age,phone){
//设置私有属性 --作为一个局部变量
var phone = phone;
this.name = name;
this.age = age;
//通过get方法来获取phone
this.getPhone = function(){
return phone; //返回
}
//通过set方法来修改设置
this.setPhone = function(num){
//设置校验规则
var reg = /\d{11}/
if(reg.test(num)){
phone=num;
}else{
alert("号码格式错误,请重新输入!!")
}
}
}
var user1 = new user("李四",29,13218452356);
//获取user1的电话号码
console.log(user1.getPhone()); //13218452356
//设置user1的电话号码
user1.setPhone(15619865245)
console.log(user1.getPhone()); //15619865245
</script>