Day02·面向对象的四个特点
-
面向对象编程的特点:
1) 抽象性:通过对象来分析具体问题;
2) 封装性:将属性和方法封装到对象中,优点是安全、便于维护;
3) 继承性:将对象属性和方法进行传递;
4) 多态性:一个类产生多种对象;(js中用不到) -
构造函数常用方法:
1) 语法:obj instanceof 数据类型 ? 判断变量对应的数据类型;
2) 语法:构造函数.prototype.isPrototypeOf(obj) ?(原型中的方法)判断对象是否是对应的构造函数中创建的;
3) 语法:obj.hasOwnProperty(key) ? 判断此对象对应的属性是否存在于构造函数中;
4) 语法:key in obj ? 判断对象是否具有此属性;
面试题://编写一个方法,分别传入 对象 和一个key,判断这个key 是否存在与 当前对象的原型上 ,返回 t或f
分析:
1) 先判断对象obj中是否有key这个属性;
2) 如果没有,返回false;
3) 如果有,再判断key这个属性是否在构造函数中;是则返回false,不是则返回true;
function Student(name,age){
this.name=name;
this.age=age;
}
Student.prototype.count=1;
let s1=new Student(“王五”,21);
function hasPrototype(obj,key){
return key in obj && obj.hasOwnProperty(key)==false;
}
console.log(hasPrototype(s1,”count”)//true
5) 语法:.call(对象,参数1,参数2) ? 改变this的指向;
语法:.apply(对象,[arr]) ? 改变this的指向(参数以数组的形式传参); -
公有属性、私有属性:
公有属性:可以任意访问和修改的属性;
私有属性:必须通过方法才能访问、修改的属性;
function User(name,pass,){
var pass=pass;//私有属性
this.name=name;//公有属性
//通过方法设置属性
this.setPass=function(num){
pass=num;
}
//通过方法获取属性
this.getPass=function(){
return pass;
}
}
let u1=new User(“admin”,123);
console.log(u1.pass)//undefined 访问不到
console.log(u1.getPass());//123 通过方法才能访问到
u1.setPass(456);//通过方法修改属性
console.log(u1.getPass());//456 -
继承性:子类继承父类的方法和属性
//父类
function Animal(name,color){
this.name=name;
this.color=color;
}
Animal.prototype.eat=function(){
console.log(this.name+”正在吃”);
}
//子类
1) 原型链继承:将原型改成对应的对象;
function Dog(name,color){
}
Dog.prototype=new Animal(“桃桃”,”黄色”);
let d1=new Dog(“臭臭”,”red”);
console.log(d1.name)//桃桃
d1.eat()//桃桃正在吃
问题:由上面打印看到,对象d1无法初始化对应的属性
2) 冒充继承:通过.call()或.apply()改变this指向实现继承;
function Cat(name,color){
Animal.call(this,name,color);
}
let c1=new Cat(“小米”,”白色”)
console.log(c1.name)//小米
c1.eat()//c1.eat is not a function 没继承过来
问题:无法继承原型链上的方法和属性
3) 混合继承:最终形态
function Bird(name,color){
Animal.call(this,name,color);
}
Bird.prototype=new Animal();
let b1=new Bird(“鹦鹉”,”红色”)
console.log(b1.name)//鹦鹉
b1.eat()//鹦鹉正在吃 -
原型链:(即访问对象的属性和方法时的查找顺序:先找构造函数内部再找原型上)