js的面向对象

什么是面向对象

  • 面向对象程序设计(Object Oriented Programming,OOP)是一种计算机编程架构。
  • 面向对象是一种软件开发方法,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的灵活性、重用性和扩展性。
  • 面向对象是不是语法,是一个思想,是一种编程模式,一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物,是一种高级的编程思想。
  • 面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。

面向对象的特征

  1. 封装
    封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。该逻辑单元负责将所描述的属性隐藏起来,外界对客体内部属性的所有访问只能通过提供的用户接口实现。对象是封装的最基本单位。
  2. 继承
    继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
  3. 抽象
    继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
  4. 多态
    多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。

类与对象

  • 描述了一组有相同特性和相同行为的对象,具有相同属性和相同方法的对象的抽象就是类。
  • 类的实例是对象
  • 对象把数据及对数据的操作方法放在一起,作为一个相互依存的整体。
  • 对象的抽象是类
类与对象的关系:模板 -> 产品

“JavaScript中所有事物都是对象”,如 字符串、数组、函数…等等。
因为所有对象均继承自Object,都是Object的实例。
对象是带有属性和方法的集合。

  • 变量和属性:
    变量是自由的,属性是属于对象的,是与对象相关的值。
  • 函数和方法:
    函数是自由的,方法是属于对象的,是与对象相关的函数
var a =‘qwe’; // 变量
alert( a );

var obj = {}; // 对象
obj.name =  ‘xiaocuo’; // 属性
obj.age = 25; // 属性
obj.sayHi = function (){ // 方法
    alert(‘hi,大家好!');
}
alert( obj.name );
obj.sayHi();

创建对象

调用系统内置的构造函数创建对象
  • js 给我们内置了一个 Object 构造函数
  • 这个构造函数就是用来创造对象的
  • 当 构造函数 和 new 关键字连用的时候,就可以为我们创造出一个对象
var o1 = new Object()
o1.name = 'Jack'
o1.age = 18
o1.sex = '男'
字面量的方式创建一个对象
  • 直接使用字面量的形式,也就是直接写 {}
  • 可以在写的时候就添加好成员,也可以动态的添加
// 字面量方式创建对象
var o1 = {
name: 'Jack',
age: 18,
sex: '男'
}
// 再来一个
var o2 = {}
o2.name = 'Rose'
o2.age = 20
o2.sex = '女'
使用工厂函数的方式创建对象
  • 工厂模式是软件工程领域一种常见的设计模式,这种模式抽象了创建对象的具体过程。
  • 这个工厂函数里面可以创造出一个对象,并且给对象添加一些属性,还能把对象返回.
  • 原料 => 加工 => 出厂
// 1. 先创建一个工厂函数
function createObj() {
// 手动创建一个对象(原料)
var obj = new Object()
// 手动的向对象中添加成员(加工)
obj.name = 'Jack'
obj.age = 18
obj.sex = '男'
// 手动返回一个对象(出厂)
   return obj
}
// 2. 使用这个工厂函数创建对象
var o1 = createObj()
var o2 = createObj()
使用自定义构造函数创建对象
  • 工厂函数需要经历三个步骤
  1. 手动创建对象
  2. 手动添加成员
  3. 手动返回对象
  • 构造函数会比工厂函数简单一下
  1. 自动创建对象
  2. 手动添加成员
  3. 自动返回对象
  • 先书写一个构造函数,在构造函数内向对象添加一些成员
  • 使用这个构造函数创造一个对象(和 new 连用)
  • 构造函数可以创建对象,并且创建一个带有属性和方法的对象
  • 面向对象就是要想办法找到一个有属性和方法的对象
  • 面向对象就是我们自己制造 构造函数 的过程
// 1. 先创造一个构造函数
function Person(name, gender) {
this.age = 18
this.name = name
this.sex = sex
}
// 2. 使用构造函数创建对象
var p1 = new Person('Jack', 'man')
var p2 = new Person('Rose', 'woman')

构造函数详解

构造函数的基本使用
  • 和普通函数一样,只不过 调用的时候要和 new 连用,不然就是一个普通函数调用
function Person() {}
var o1 = new Person() // 能得到一个空对象
var o2 = Person() // 什么也得不到,这个就是普通函数调用
  • 首字母大写
function person() {}
var o1 = new person() // 能得到一个对象

function Person() {}
var o2 = new Person() // 能得到一个对象
  • 当调用的时候如果不需要传递参数可以不写 () ,建议都写上
function Person() {}
var o1 = new Person() // 能得到一个空对象
var o2 = new Person // 能得到一个空对象
  • 构造函数内部的 this,由于和 new 连用的关系,是指向当前实例对象的
function Person() {
console.log(this)
}
var o1 = new Person() // 本次调用的时候,this => o1
var o2 = new Person() // 本次调用的时候,this => o2

注意:每次 new 的时候,函数内部的 this 都是指向当前这次的实例化对象

  • 因为构造函数会自动返回一个对象,所以构造函数内部不要写 return
    你如果 return 一个基本数据类型,那么写了没有意义。
    如果你 return 一个引用数据类型,那么构造函数本身的意义就没有了。
使用构造函数创建一个对象
  • 我们在使用构造函数的时候,可以通过一些代码和内容来向当前的对象中添加一些内容
function Person() {
this.name = 'Jack'
this.age = 18
}
var o1 = new Person()
var o2 = new Person()
// 我们得到的两个对象里面都有自己的成员 name 和 age
  • 也可以添加一些方法进去
function Person() {
this.name = 'Jack'
this.age = 18
this.sayHi = function () {
alert('hello constructor')
}
}
var o1 = new Person()
var o2 = new Person()
  • 但是这样写有缺点
function Person() {
this.name = 'Jack'
this.age = 18
this.sayHi = function () {
console.log('hello constructor')
}
}
var o1 = new Person()
// 第一次 new 的时候, Person 这个函数要执行一遍
// 执行一遍就会创造一个新的函数,并且把函数地址赋值给 this.sayHi

var o2 = new Person()
// 第二次 new 的时候, Person 这个函数要执行一遍
// 执行一遍就会创造一个新的函数,并且把函数地址赋值给 this.sayHi

console.log(o1.sayHi === o2.sayHi) //flase
//这样的话,那么我们两个对象内的 sayHi 函数就是一个代码一模一样,功能一摸一样
//但是是两个空间函数,占用两个内存空间

  • 怎么解决呢,就需要用到一个东西,叫做 原型

原型

prototype
  • 每一个函数天生自带一个成员,叫做 prototype,是一个对象空间
  • 即然每一个函数都有,构造函数也是函数,构造函数也有这个对象空间
  • 这个 prototype 对象空间可以由函数名来访问
function Person() {}

console.log(Person.prototype) // 是一个对象
  • 即然是个对象,那么我们就可以向里面放入一些东西
function Person() {}

Person.prototype.name = 'prototype'
Person.prototype.sayHi = function () {}

在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的

__ proto __
  1. 每一个对象都天生自带一个成员,叫做 __ proto __ ,是一个对象空间
  2. 即然每一个对象都有,实例化对象也是对象,那么每一个实例化对象也有这个成员
  3. 这个 __ proto __ 对象空间是给每一个对象使用的
  4. 当你访问一个对象中的成员的时候
  • 如果这个对象自己本身有这个成员,那么就会直接给你结果
  • 如果没有,就会去 __ proto __ 这个对象空间里面找
  • 这个对象是由哪个构造函数 new 出来的,那么这个对象的 __ proto __ 就指向这个构造函数的 prototype
function Person() {}

var p1 = new Person()

console.log(p1.__proto__ === Person.prototype) // true
  • 我们发现实例化对象的 __ proto __ 和所属的构造函数的 prototype 是一个对象空间
  • 我们可以通过构造函数名称来向 prototype 中添加成员
  • 对象在访问的时候自己没有,可以自动去自己的 __ proto __ 中查找
function Person() {}
//我们可以把函数放在构造函数的 prototype 中
Person.prototype.sayHi = function () {
console.log('hello Person')
}

var p1 = new Person()
//p1 自己没有 sayHi 方法,就会去自己的 __proto__ 中查找
//p1.__proto__ 就是 Person.prototype
p1.sayHi()
  • 当我们实例化多个对象的时候,每个对象里面都没有方法
function Person() {}

Person.prototype.sayHi = function () {
console.log('hello')
}

var p1 = new Person()
//p1 是 Person 的一个实例
var p2 = new Person()
//p2 是 Person 的一个实例
console.log(p1.sayHi === p2.sayHi)
//都是去所属的构造函数的 protottype 中查找
//p1.__proto__ 和 p2.__proto__ 指向的都是 Person.prototype
//每一个对象使用的函数,其实都是同一个函数
//

这样就解决了构造函数的缺点

结论

  • 当我们写构造函数的时候
  • 属性我们直接写在构造函数体内
  • 方法写在原型上

原型链

一个对象所属的构造函数
  • 每一个对象都有一个自己所属的构造函数
  • 比如 :数组
// 数组本身也是一个对象
var arr = []
var arr2 = new Array()
//数组所属的构造函数就是 Array
  • 比如 :函数
// 函数本身也是一个对象
var fn = function () {}
var fun = new Function()
// 我们就说函数所属的构造函数就是 Function

constructor

  • 对象的 __ proto __ 里面也有一个成员叫做 constructor
  • 这个属性就是指向当前这个对象所属的构造函数,可以用来判断复杂数据类型
链状结构
  • 当一个对象我们不知道准确的是谁构造的时候,我们就把它看成 Object 的实例化对象
  • 也就是说,我们的 构造函数 的 prototype 的 __ proto __ 指向的是 Object.prototype
  • 那么 Object.prototype 也是个对象
  • 因为 Object 的 js 中的顶级构造函数,我们有一句话叫 万物皆对象
  • 所以 Object.prototype 就到顶了, Object.prototype 的 __ proto __ 就是 null
原型链的访问原则
  • 之前说过,访问一个对象的成员的时候,自己没有就会去 __ proto __ 中找
  • 接下来就是,如果 __ proto __ 里面没有就再去 __ proto __ 里面找
  • 一直找到 Object.prototype 里面都没有,那么就会返回 undefiend
对象的赋值
  • 如果是赋值的话,那么也会按照原型链的规则来
  • 赋值的时候,就是直接给对象自己本身赋值
  • 如果原先有就是修改,原先没有就是添加,不会和 __ proto __ 有关系

混合模式

  • 混合使用构造函数模式和原型模式,是目前JS中使用最广泛、认同度最高的一种创建对象的方法
  • 构造函数模式用于定义实例属性,原型模式用于定义共享的属性和方法
  • 即可以共享方法,又可以向构造函数传递参数,集两种模式之长!
function Person(name,sex,age){
    this.name = name;
    this.sex = sex;
    this.age = age;
}

Person.prototype.attr = '人类';
Person.prototype.eat = function (){
    alert('什么都吃');
}

var p1 = new Person('老王','男',36);
var p2 = new Person('小宋','女',26);

console.log(p1.constructor);//Person
console.log(p1.eat === p2.eat);//true

总结

  • 面向对象的思维: 当我想完成一个功能的时候
  • 先看看内置构造函数有没有能给我提供一个完成功能对象的能力
  • 如果没有,我们就自己写一个构造函数,能创造出一个完成功能的对象
  • 然后在用我们写的构造函数 new 一个对象出来,帮助我们完成功能就行了
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值