javascript中的面向对象详解

什么是面向对象
  • 用对象的思想去写代码,就是面向对象棉城
面向对象的特点
  • 抽象: 抓住核心问题
  • 封装:只能通过对象来访问方法
  • 继承:从已有对象上继承出新的对象
  • 多态:多对象的不同形态
对象的组成
  • 方法:对象下面的函数叫做对象的方法
  • 属性:对象下面的变量,就叫做对象的属性
构造函数
  • 一个函数被new 调用了之后,那这个函数就是一个构造函数
  • 当new去调用一个函数的时候,那这个函数体中的this就是创建出来的对象,而且这个函数的返回值就是this(隐式返回)
function createPerson(name) {
  this.name = name;
  this.showName = function () {
    console.log(this.name)
  }
  // 这里的this就是指p这个对象,并将其返回
}
// 现在这个createPerson这个函数没有return但是这里隐式返回了p这个对象
var p = new createPerson('小明');
p.showName();
对象的引用
  • 基本类型
    赋值的时候就是值得复制

  • 对象类型
    不仅是值得复制,还包括地址的引用

var a = [1,2,3];
var b = a; // 将a的值赋值给b,并将a的地址(住的地方)给b
b.push(4); // 修改b: 在b的末尾添加4
console.log(b); // [1,2,3,4]
console.log(a); // [1,2,3,4]

var a = [1,2,3];
var b = a; // 将a的值赋值给b,并将a的地址(住的地方)给b
b = [1,2,3,4]; // 重新给b赋值,相当于在内存中重新生成了一个新的对象,和a对象没有关系了
console.log(b); // [1,2,3]
console.log(a); // [1,2,3,4]

只要在程序中赋值,那必然会在内存中重新生成,相当于将原来的值给删除了,在申明并赋值

原型 prototype
  • prototype原型对象: 默认每个函数对象都有prototype属性,prototype对象中默认有一个constructor
  • __proto__原型属性:默认每个对象都有__proto__ 属性,改属性默认指向创建对象对应的构造函数中的prototype
  • js中的对象都是基于原型的对象,使用prototype的目的就是资源共享
    在这里插入图片描述
  • 对象属性调用:
    先在自身空间中查找,如果有就直接使用,没有就在原型中查找; 如果原型不存在,就在原型的原型中查找(这种链式的关系称之为原型链),如果一直不存在,最终会找到原型链的终点(Object.prototype),如果在终点中还没有找到,待调用改属性,则返回undefined
    在这里插入图片描述
对象的继承
  • 构造函数的的继承

    缺点:不能继承父类原型的方法

function Parent(name) {
  this.name = name
}
Parent.prototype.createMethods = function () {
  console.log(this.name);
}
function Child(name,age) {
  Parent.call(this, name);
  this.age = age;
}
var c = new Child('张山', 18)
console.log(c.name) // 张山
console.log(c.age) // 18
console.log(c.createMethods) // undefined
  • 原型连继承

    缺点: 当你在子类的原型添加新的方法的时候,在父类的原型上也会有这个方法, 并且父类和子类的constructor都指向父类

function Parent(name) {
  this.name = name;
}
Parent.prototype.showName = function () {
  return  this.name;
}
function Child(name, age) {
  Parent.call(this, name);
  this.age = '18';
}
Child.prototype = Parent.prototype; // 对象的引用
Child.prototype.showAge = function () {
  return this.age
}
var p = new Parent();
var c = new Child('张珊', 18);
console.log(c.name); // 张珊
console.log(c.age); // 18
console.log(c); 
console.log(p); // 此时你在p的原型上也可以看到showAge这个方法
console.log(c.constructor === p.constructor) // 父类实例和子类实例的constructor都指向父类
  • 组合继承

那种通过这种方式就可以完美的解决问题了面向对象的继承的问题

function Parent(name) {
  this.name = name;
}
Parent.prototype.showName = function () {
  return  this.name;
}
function Child(name, age) {
  Parent.call(this, name);
  this.age = '18';
}
Child.prototype = Object.create(Parent.prototype); // 实现继承
Child.prototype.constructor = Child; // 指定子类的构造函数为子类
var p = new Parent();
var c = new Child('张珊', 18);
console.log(c.constructor === p.constructor)
console.log(c.name); // 张珊
console.log(c.age); // 18
console.log(c); 
console.log(p);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值