一.理解面向对象与面向过程的不同?
面向过程和面向对象是两种主要的编程思想,在解决问题的方式、程序的组织结构,代码的可维护性和可扩展性都有着显著的不同。
面向过程强调的是功能行为,把解决问题的步骤依次实现,关注的是解决问题的流程。它首先分析出解决问题需要的步骤,然后用函数将这些步骤依次调用实现。面向过程的优点在于流程化具体步骤清楚,便于节点分析,效率高,代码短小精悍,善于结合数据结构来开发高效率的程序。然而,面向过程的缺点在于代码重用性低,扩展能力差,后期维护难度比较大,因为修改其中的一部分可能就要在全部地方修改,牵一发而动全身。
面向对象是一种编程思想,是对面向过程的封装,对象是容器,里面封装了属性和方法,面向对象可以让代码有可复用性和维护性,可拓展性,提高代码的开发效率,面向对象有三大特征:封装性、继承性、多态性。
1.面向对象的三大特征:封装性、继承性、多态性
封装性:将对象的属性和方法绑定在一起,提高代码的安全性、可靠性和维护性。
// 构造函数
function Animal(c,w,uname){
this.color=c
this.weight=w
this.uname=uname
}
// 原型对象
Animal.prototype.eat=function(){
console.log(`${this.weight}重${this.color}的${this.uname}在吃东西`);
}
// 创建的动物实例以及调用原型上的方法
new Animal('红色','五斤','小狗').eat()
继承性:一个对象可以拥有另一个对象的属性和方法。
// 父对象(构造函数)
function Animal(c, w, uname) {
this.color = c;
this.weight = w;
this.uname = uname;
}
// 原型对象
Animal.prototype.eat = function () {
console.log(`${this.weight}重${this.color}的${this.uname}在吃东西`);
};
// 子对象(构造函数)
function mouse(age, c, w, uname) {
this.age = age;
// 继承父元素属性 改变this指向的方法 apply call bind
// 在子对象上面写 (把Animal函数作用域的this指向Loin函数作用域)
Animal.apply(this, [c, w, uname]);
// Animal.call(this, c, w, uname);
// Animal.bind(this)(n, c, w);
}
// 原型对象
mouse.prototype.shout = function () {
console.log(`${this.age}岁的${this.uname}在叽叽叽的发出叫声`);
};
// 继承父元素的方法,把Animal原型上的方法复制到Loin构造函数原型上
mouse.prototype.eat = Animal.prototype.eat;
var m1 = new mouse(2, "黄白色", "四斤", "金丝熊");
m1.eat();
m1.shout();
多态性:不同的对象不同的方法传入参数的不通过会有不一样的表现形式。
function Animal(c,w,uname){
// 添加属性
this.color=c
this.weight=w
this.uname=uname
}
// 原型对象
Animal.prototype.eat=function(){
console.log(`${this.weight}重${this.color}的${this.uname}在吃东西`);
}
// 第二个原型对象
Animal.prototype.show=function(){
if(this.uname=='猫'){
console.log(`${this.color}的${this.uname}在喵喵叫`);
}else if(this.uname=='狗'){
console.log(`${this.color}的${this.uname}在汪汪的叫`);
}
}
// 创建对象实例
var m1= new Animal('黄色','十五斤','狗')
// 对象实例调用原型上的方法
m1.eat()
m1.show()
// 创建对象实例
var m2=new Animal('白色','五斤','猫')
// 对象实例调用原型上的方法
m2.eat()
m2.show()
二.如何构建对象?
在JS中创建对象有三种方法
- 直接使用字面量创建对象
- 使用
Object.create()
方法 - 使用构造函数创建对象
1.直接量
// 1)直接量
var car = {
color: "白色",
brand: "特斯拉",
drive: function () {
console.log(`驾驶${car.color}的${car.brand}汽车`);
},
};
car.drive();
(直接var 变量添加属性以及方法)
2.工厂模式
function factory(color, brand) {
var obj = {};
obj.color = color;
obj.brand = brand;
obj.drive = function () {
console.log(`驾驶${obj.color}的${obj.brand}汽车`);
};
return obj;
}
var car1 = factory("红色", "大宗");
car1.drive();
(手动添加一个函数,在函数内部通过Object类创建对象,添加属性和方法,再return 返回该对象)
3.构造函数
function Car(color, brand) {
this.color = color;
this.brand = brand;
this.drive = function () {
console.log(`驾驶${this.color}的${this.brand}汽车`);
};
}
var car3 = new Car("橙色", "宝马");
console.log(car3);
car3.drive()
(系统去构造对象,通过new操作符创建对象以及返回对象,该对象可以访问构造函数内的方法属性)
三.new操作符做了什么?
创建空对象,返回临时对象,new出来的对象原型指向构造函数的prototype, this指向这个对象,执行构造函数
四.this是什么?
this 是个指针变量 指向作用域上下文的对象,可以指向某个对象
this 由作用域或者调用者决定,在不同的作用域下,this代表的是不同的数据
this 在构造函数作用域中,指向构造函数new出来的实例,在全局作用域中指向window
挂载到this对象上的数据,所属构造函数的实例就可以使用