面向对象概念
两种编程模式:
面向过程:注重过程
面向对象:注重结果
Js基于对象
对象的特征:
封装 继承 多态
对象的组成:
属性:静态的,对象的描述 --------------------- 变量
方法:动态,对象的行为 -------------------------- 函数
面向对象创建方式
new(单例创建):创建出来的永远是一个对象
var obj1 = new Object();
//添加属性
obj1.name = "如花";
obj1.age = 18;
obj1.height = 192;
//方法
obj1.kou = function(){
console.log("扣那个啥");
}
console.log(obj1);
问题:适合创建单个对象,代码冗余
字面量创建
var obj3 = {
name:"乔碧萝",
age:48,
height:150,
ps:function(){
console.log(this.name+"是颜值主播,10万露脸");
}
}
console.log(obj3);
obj3.ps();
适合创建单个对象,多个对象会代码冗余
工厂模式创建
function createObj(name,age,height) {
var obj = new Object();
//添加属性
obj.name = name;
obj.age = age;
obj.height = height;
//方法
obj.angry = function () {
console.log("生气,打一顿就好了");
}
return obj;
}
//2.实例化对象
var obj = createObj("柳岩",35,160);
var obj2 = createObj("旺财",2,30);
console.log(obj instanceof Object);//true 实例是否由某个对象创建
问题:解决代码冗余的问题,分类不明确,识别不清楚
构造函数创建
构造函数是最常用的创建方式
特征:
1.函数名首字母大写,为了区分普通函数
2.不需要在里面创建对象,给this添加属性和方法,不需要返回
3.调用前面必须要加new
function Student(name,age,sex){
//var obj = new Object()
//this = obj
//return obj;
this.name = name;
this.age = age;
this.sex = sex;
this.study = function(){
console.log("good good study,day day up!!!");
}
}
//2.实例化对象
var s1 = new Student("小花",8,"男");
var s2 = new Student("旺财",2,"女");
console.log(s1);
console.log(s2);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VVc6kAdb-1573693671670)(E:\第二阶段\day14 面向对象\1572508738430.png)]
new操作符做了什么?
1.创建了一个空对象
2.让this指向这个空对象,
3.让空对象的_proto_指向构造函数的prototype
4.隐式的返回创建的对象
问题:
console.log(s1.study==s2.study);//地址 false
//解决类型识别问题,但是会造成内存浪费
原型创建
每一个函数,都有一个原型对象prototype,里面存储这个类型公共,公用的属性和方法
原型对象:函数名.prototype
原型属性: 实例对象.proto
function Student(){}
//1.在原型中添加公共的属性和方法
Student.prototype.name = "小明";
Student.prototype.age = 8;
Student.prototype.study = function(){
console.log("好好学习,好好吃饭,早早睡觉");
}
//3.实例化对象
var s1 = new Student();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eg50RNJJ-1573693671672)(E:\第二阶段\day14 面向对象\1572508884596.png)]
问题:解决内存浪费的问题,但是不能传参
混合创建
//混合创建:构造函数(可变的属性和方法)+原型(共享的不变的属性和方法)
//1.声明构造函数
function Student(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
//2.原型 共享
Student.prototype = {
height:130,
study:function(){
console.log("好好吃饭,好好睡觉")
},
play:function(){
console.log("好好玩");
}
}
//3.实例化对象
var s1 = new Student("小明",8,"男");
console.log(s1);
var s2 = new Student("小夏",12,"女");
console.log(s2);
原型链:先在自己实例对象中找,没有找_proto_
call与apply与bind
都是用来改变this的指向
call:函数名.call(this的指向,参数1,参数2)
apply: 函数名.apply(this,[参数1,参数2])
function fun1(a,b){
console.log(this);
console.log((a+b));
}
fun1.call(obj1,10,20);
fun1.apply(obj1,[10,20]);
bind:创建一个新的函数返回,返回的函数是改变this之后的函数
//bind:创建一个新的函数返回,返回的函数是改变this之后的函数
function fun2(){
console.log(this);
}
var f = fun2.bind(obj1); // function fun2(){console.log(obj1));}
f();
面向对象继承
原型链继承
//1.父类型
function Student(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.arr = [1,2,3];
}
Student.prototype = {
height:"130",
study:function(){
console.log("学生的主要任务是学习");
}
}
//2.子类
function SmallStudent(){
this.play = function(){
console.log("吃鸡");
}
}
//3.原型链继承操作 子类,prototype = 父类的实例对象
SmallStudent.prototype = new Student("蜡笔小新",3,"男");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kCAI2vAX-1573693671673)(E:\第二阶段\day14 面向对象\1572509128686.png)]
问题:不能传参,如果继承到引用类型数据,一改全改
对象冒充继承
function SmallStudent(name,sex,age) {
//对象冒充
Student.call(this,name,age,sex);
this.play = function () {
console.log("吃鸡");
}
}