JS高级面向对象(二)-构造函数和原型

二,构造函数和原型

1,创建对象的三种方式

在es6之前,是没有class类这个概念的,创建类都是用构造函数创建的

创建对象的三种方式

  1. 对象字面量

    var obj = {};
    
  2. new Object()

    var obj = new Object()
    
  3. 自定义构造函数

    function People() {
        this.name = name;
        this.age = age;
        this.sing = function() {}
    }
    

创建实例分为四步:

  1. 开辟一个新空间
  2. 执行构造函数里面的代码
  3. 把this里面的属性都赋值给这个空间
  4. 返回这个空间给new的哪个变量

2,静态成员和实例成员

通过this添加的属性叫做实例,通过给函数本身添加的属性教静态成员

  1. 实例成员
    function People() {
        this.name = name;		// 实例成员
        this.age = age;			// 实例成员
    }
    var a = People()
    console.log(a.name)		// 实例成员只能通过访问属性的方式访问
    
  2. 静态成员
    function People(name, age) {
        this.name = name;
        this.age = age;
    }
    People.other = '静态成员';
    console.log(People.other);		// 静态成员只能通过构造函数的方式来访问
    

在这里插入图片描述

每个通过构造函数创建的实例都会有性能浪费的问题,实例里面的方法存放的地址是不一样的!!!!
function People(name, age) {
    this.name = name;
    this.age = age;
    this.say = function() {
        console.log(this.name + '说话了');
    }
}
class People1 {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    say() {
        console.log(this.name + '说话了');
    }
}
var a = new People('a', 20);
var b = new People('b', 21);
console.log('构造函数中: ' + (a.say === b.say)); // 在构造函数中方法是存不同地方的

var a1 = new People1('a1', 20);
var b1 = new People1('b1', 21);
console.log('类中: ' + (a1.say === b1.say)); // 在类中方法是存在一个地方的

3,构造函数原型对象:prototype

  • 构造函数通过原型分配的函数是所有对象共享的

  • JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,之一这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被够着函数所有(本质上解决了不同实例的函数指向,解决了内存浪费)

    function People(name, age) {
        this.name = name;
        this.age = age;
        this.sing = function() {}
    }
    
    var a = new People('xyb', 20);
    var b = new People('lyw', 19);
    console.log(a.sing === b.sing); // 两个实例的方法不是同一个!
    
    People.prototype.say = function() {}
    console.log(a.say === b.say);	// 两个实例的方法是同一个!
    
  1. 原型是什么?

    一个对象,我们也称 prototype 原型对象

  2. 原型的作用是什么?

    共享方法,解决构造函数实例出来的对象方法性能浪费问题

  • 一般情况下,我们公共属性定义到构造函数里面,公共方法定义在原型对象身上

4,实例对象原型:__ proto __

实例都会有一个属性 __ proto__ 指向构造函数的原型,之所以实例对象可以使用构造函数原型中的函数,就是因为有 __ proto__ 这个属性的指向

实例对象的__proto__ 和构造函数的 prototype 是等价的

function People(name, age) {
    this.name = name;
    this.age = age;
}

People.prototype.sing = function() {
    console.log(this.name + '说话了');
}

var a = new People('xyb', 20);
console.log('a.__proto__:' + a.__proto__);
console.log('People.prototype:' + People.prototype);
console.log(a.__proto__ === People.prototype);
  • 方法的查找顺序:
    1. 如果构造函数创造函数的时候有方法,就使用构造函数里的
    2. 如果没有,则在对象的__ proto __ 属性中查找,也就是在构造函数的原型中查找

5,constructor 构造函数

对象原型(__ proto __) 和 构造函数(prototype)原型对象里面都有一个 constructor 属性,它指回构造函数

  1. 作用:用来指明是引用了哪个构造函数,它可以让原型对象指挥原来的构造函数

  2. 因为构造函数的原型和实例的原型是同一个对象,所以他们原型的 constructor 是相同的

    console.log(a.__proto__.constructor === People.prototype.constructor); // true
    
  3. 很多情况下,我们需要手动的利用 constructor 这个属性指回原来的构造函数

    function People(name, age) {
        this.name = name;
        this.age = age;
    }
    
    People.prototype = {
        // 这里我们是重新把构造函数的原型对象重新赋值了,所以需要重新手动添加初始化函数
        constructor: People,
        sing: function() {
            console.log(this.name + '唱歌了');
        },
        say: function() {
            console.log(this.name + '说话了');
        }
    }
    
    var a = new People('xyb', 20);
    console.log(a.__proto__);
    console.log(People.prototype);
    console.log(a.__proto__.constructor);
    console.log(People.prototype.constructor);
    

6,构造函数丶实例丶原型对象三者之间的关系

在这里插入图片描述

7,JavaScript 的成员查找机制

  1. 当访问一个对象的属性(包括方法),首先看看,构造函数有没有创建这些方法或属性

  2. 如果找不到,就去这个对象的原型(也就是__ proto __和prototype指向的原型对象中)里面找

  3. 如果没有找到就一直往上找,也就是原型对象的原型里面找(object的原型对象)

  4. 以此类推,直到查到Object原型对象为null时停止

    function People(name, age) {
        this.name = name;
        this.age = age;
    }
    
    People.prototype = {
        // 这里我们是重新把构造函数的原型对象重新赋值了,所以需要重新手动添加初始化函数
        constructor: People,
        sing: function() {
            console.log(this.name + '唱歌了');
        },
        say: function() {
            console.log(this.name + '说话了');
        }
    }
    Object.prototype.sex = 'obj的sex'
    People.prototype.sex = 'peo的sex'
    var a = new People('xyb', 20);
    console.log(a.sex);         // a本身没有sex属性,去他的原型里面找,原型没有就去原型的原型里面找
    

8,原型对象this指向

function People(name, age) {
    this.name = name;
    this.age = age;
    console.log('构造函数中的this:', this);

}
People.prototype.say = function() {
    console.log('原型对象中的this:', this); // 谁调用了这个say方法,this就指向谁
}

var a = new People('xyb', 20); // People {name: "xyb", age: 20}
var b = new People('lyw', 19); // People {name: "lyw", age: 19}
// 1. 构造函数中的this指向的是对象实例
a.say(); // People {name: "xyb", age: 20}
b.say(); // People {name: "lyw", age: 19}

案例2:利用原型扩展内置对象方法

通过原型对象,对原来的内置对象进行扩展自定义方法,比如给数组增加求和方法

Array.prototype.sum = function() {
    var total = 0;
    for (var i = 0; i < this.length; i++) {
        total += this[i];
    }
    return total
}
var arr = new Array(10, 20, 30);
console.log(arr.sum());				// 60

// ----------错误示例----------这里直接把Array的原型对象覆盖掉了
Array.prototype ={
    sum: function() {
        var total = 0;
        for (var i = 0; i < this.length; i++) {
            total += this[i];
        }
        return total
    }
}
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值