JS中的面向对象

一、介绍

1.编程思想有三种:

面向过程编程POP:分析出问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以。

面向对象编程OOP:把事物分解成一个个对象,然后由对象分工与合作,每一个函数,一定会有一个原型,属性的选择性放在实例化的对象中,函数写在原型上

函数式编程FP:把现实世界 的事物和事物之间的联系抽象到程序里,用来描述数据之间的映射,相同的输入始终要得到相同的输出。

2.优点:

具有灵活性,代码可服用,容易维护和开发

3.面向对象的特性:

封装性(低耦合,高内聚),继承性(子类继承父类中的一些属性和方法),多态性(重载)

4.new  Foo()返回一个对象,这个对象叫做函数的实例化。(实例化出来的对象与函数同名)

5.new函数,函数就变成了构造函数(函数首字母大写,会返回构造函数的同名对象,每次调用都会产生一个新对象)

6.面向对象的思维特点:

  抽取对象共用的属性和方法封装成一个类

  对类进行实例化,获取类的对象,每实例化一次就产生一个新的对象

7.对象:是一组无序的相关属性和方法的集合

              属性:事物的特征,在对象中用属性来表示

              方法:事物的行为,在对象中用方法来表示

8.构造函数:用来初始化新创建对象的函数,里面有一个属性是prototype,改属性指向了实例对象的原型对象

   实例对象:通过new构造函数,会返回一个对象,这个就是实例对象,有一个__proto__属性指向了构造函数的prototype属性

   原型对象:构造函数的prototype指向的就是原型对象

二、面向过程和面向对象对比

面向过程:

优点:性能比面向对象高,适合跟硬件联系紧密的东西,如单片机采用的就是面向过程

缺点:没有面向对象易维护,易复用,易扩展

面向对象:

优点:易维护,复用,扩展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更加灵活,更加易于维护

缺点:性能低

三、构造函数

1.概念:当将这个函数进行new,这个函数就成构造函数,为了与普通函数区别,构造函数的名第一个字母大写。

2.特点:函数体内使用了this关键字,代表了所要生成的对象实例(this指向最近一层函数包裹并返回当前函数的调用对象)

              生成对象,必须使用new关键字实例化

四、原型

1.每个函数产生都会伴随一个原型(prototype)产生,一个实例对象产生都会产生一个__proto__指针,指向了构造函数的prototype属性

2.给构造函数的prototype属性(对象)添加一个方法,这个方法就可以被构造函数的实例所共享

Student指构造函数
s1指实例的对象
Student.prototype.constructor===s1.constructor===Student
Student.prototype.__proto__===s1.__proto__.__proto__===Object.prototype
Object.prototype.constructor === Object
Student.prototype===s1.__proto__
s1.__proto__.__proto_.__proto__ === Object.prototype.__proto__ === null
Student.constructor === Object.constructor=== Function
Function.prototype === Student.__proto  === Object.__proto__
Function.prototype.constructor === Function
Function.prototype.__proto === Object.prototype

3.总结

每创建一个函数,该函数就会自动带有一个 prototype 属性(原型对象)。该属性是个指针,指向了一个对象。

原型对象上默认有一个属性 constructor,该属性也是一个指针,指向其相关联的构造函数。

通过new构造函数产生的对象实例,都有一个内部属性__proto__,指向了prototype原型对象。

所以对象实例能够访问构造函数原型对象上的所有属性和方法。

通俗点说就是,实例通过内部指针__proto__可以访问到原型对象,原型对象通过constructor指针,又可以找到构造函数。

__proto__是每个对象都有的一个属性,而prototype是函数才会有的属性。

function PC(type,brand,price){
    this.type = type;
    this.brand = brand;
    this.price = price;
}
PC.prototype.playSong = function(){
    return "播放歌曲";
}
var pc = new PC('T460P',"联想",15999);
console.log(PC.prototype);  //{playSong: ƒ, constructor: ƒ} 构造函数的原型对象
console.log(pc.__proto__);  //{playSong: ƒ, constructor: ƒ} 指向了构造函数的原型对象
console.log(pc.__proto__.__proto__);  //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, …} 构造函数的prototype上的__proto__指向内置构造函数的Object的原型对象
console.log(pc.__proto__.__proto__.__proto__);  //null  内置构造函数Object的原型对象中的__proto__指针指向为null

4.js继承机制:通过原型对象实现继承

原型对象的作用:定义所有实例对象共享的属性和方法

5.原型链:所有的对象都有自己的原型对象,对象的原型就是原型的原型,一层一层的查找,所有对象的原型最终都可以寻找到Object.prototype,所有对象都继承了Object.prototype的属性和方法

注:如果对象和它的原型,都定制了同名的属性,那么优先读取对象自身的属性
        一但修改了构造函数的原型对象,为防止引用出现问题,同时也要修改原型对象的constructor属性

五、constructor属性

1.每个对象在创建时都会自动拥有一个构造函数属性constructor

2.constructor是通过继承关系继承下来的,当前实例的对象父类就是__proto__,里面就有constructor属性,它继承了原型对象,constructor指向了当前的构造函数

3.constructor属性表示原型对象和构造函数之间的关联关系

Student===s1.constructor

 

六、new命令的原理

1.新生成一个对象,作为将要返回的对象实例

2.将这个空的对象原型对象,指向了构造函数的prototype属性对象

3.将这个实例对象的值赋值给函数内部的this关键字(也就是this就是new完的实例对象)

4.执行构造函数体内的代码,返回新对象

function create() {
  let obj = new Object()
  let Con = [].shift.call(arguments)
  obj.__proto__ = Con.prototype
  let result = Con.apply(obj, argument)
  return typeof result === 'object' ? result : obj
}

七、继承:

1.原型继承

(1)把父类的实例作为子类的原型

Son.prototype = new Father()

(2)父原型对象赋值子原型对象

Son.prototype = Father.prototype

2.实例继承/冒充继承(call、apply):只复制了属性,没有复制到原型里的东西

function  Father(name,age){  }
function  Son(name,age){  Father.call(this,name,age);}
function  Son(name,age){  Father.apply(this,[name,age]);}
function  Son(name,age){  Father.apply(this,arguments);}
//call的是一个个的参数列表;apply的是一个数组(arguments也可以)

 

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值