JavaScript中的面向对象

面向对象


对象与原型对象
1.对象的分类
原生对象
内置对象
Date、Math、正则、数组等,直接使用
自定义对象
开发人员自己定义的对象,例如使用{}快速生成对象
宿主对象
依存于某一个特定的环境才会有的对象。一旦离开了特定的环境,则这些对象将不存在。
在ES6中,对象的类别得到了扩充,分为了4个类别,分别是普通对象,外来对象,标准对象和内置对象。
2原型对象
在JS里没有类的概念,在js里每个对象都有一个原型对象,原型对象上面也有自己的原型对象,一层层向上找,最后找到null

 



每个对象都有一个原型对象,我们可以通过 __proto__来访问到某个对象的原型对象
通过__proto__一直向上找原型对象,最终会找到null
一个构造函数的prototype属性指向一个对象,而这个对象是通过该构造函数实例化出来的对象的原型对象
JS中的根对象是Object.prototype对象,Object.prototype对象是一个空对象,在JS中遇到的没一个对象,实际都是从Object.prototype对象克隆而来的
Object.prototype对象就是他们的原型。而Object.prototype对象原型为null


类与对象的创建


构造函数
在ES6之 前都没有类的概念(注: ES6新增了class关键字),而是通过构造函数来模拟其他编程语言里面的类的。构造函数实际上也是函数,不过这种函数是专门用于生产对象的,所以被称之为构造函数。
构造函数的函数名有一个不成文的规定,就是首字母要大写,以便和普通函数进行区分。
用new运算符调用函数时,该函数总会返回一个对象,通常情况下,构造函数里面的this就指向返回的这个对象
ES6类的声明
使用class关键字,来创建类,然后从类里面实例化对象。
注:虽然有了class关键字,但他只是一种语法糖,背后对象创建,还是使用原型的方式
静态方法
又被称之为类方法。顾名思义,就是通过类来调用的方法。静态方法的好处在于不需要实例化对象,直接通过类就能够进行方法的调用
在ES6创建类的方法的时候,可以给方法前面添加一个关键字static,来创建-一个静态方法。


与原型相关的方法


1. prototype和_ proto_
prototype是构造函数上面的-一个属性,指向-一个对象,这个对象是构造函数实例化出来的对象的原型对象。实例化出来的对象可以通过_proto_ 来找到自己的原型对象。
2.Object.getPrototypeOf
constructor属性
instanceof操作符
判断一个对象是否是一个构造函数的实例。如果是返回true,否则就返回false


封装


封装的基本介绍
隐藏内部的细节,不暴露在外面。目的就是将信息隐藏。
如果我们不希望所有的属性外部都能访问到,而是部分属性对外隐藏,这个时候我们就需要对这些属性进行封装了。
利用函数的作用域来进行模拟,在声明属性的时候,添加关键字(let、 const、var)即可
私有属性,有一个不成文的规定,那就是习惯使用_开头来命名私有属性。
封装后的属性,称之为私有属性。对于外部来讲,私有属性是不可见的,对于内部来讲,私有属性是可见的
存取器
get:一旦目标被访问,就会调用相应的方法
set:一旦目标被访问,就会调用相应的方法


继承


1继承基本介绍
面向对象里面的继承是指一个子类去继承一个父类,子类继承父类,父类的所有属性和方法都自动拥有了
继承的好处
继承最大的好处,就在于代码复用。例如有两个类,这两个类的属性和方法基本相同,那么我们就可以考虑给这两个类写一个父类
继承的缺点
如果继承设计得非常复杂,那么整个程序的设计也会变得庞大和臃肿
单继承,就是指只有-一个父类多继承
多继承,就是指有多个父类
菱形继承问题只会在多继承里面才会出现
这个是属于设计上的问题。
javaScript是一门单继承的语言,所以一定程度上避免了菱形继承的问题。
2对象冒充
就是用父类去充当子类的属性
借用模式
不需要继承,就可以从父类或者原型上面借用相应的属性和方法
call()和apply()方法
Funct ion. apply(obj, args )方法能接收两个参数obj:这个对象将代替Funct ion类里this对象
args:这个是数组,它将作为参数传给Funct ion(args . >arguments)

call:和apply的意思-样,只不过是参数列表不一样。
Function. call(obj, [param1[, param2[, ...[, paramN]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表

3原型继承
核心思路就是改变构造函数的prototype的指向,使其指定到我们想要继承的类的实例对象上面
4. ES6继承方式:使用extends关键字继承


this指向


普通函数中this指向
this指向全局对象。当this是在全局中使用,或者是在函数中,但是该函数不作为对象的方法,只是作为普通函数被调用时,指向的就是全局对象(node里面是global对象,浏览器环境里面是window对象)
以普通函数的方式调用的时候,无论嵌套多少层函数,this 都是指向全局对象
改变this指向
使用call或者apply来修改this指向
使用bind()方法强行绑定this指向
语法如下:fun. bind(thisArg[, arg1[, arg2[, ...]]])
thisArg 当绑定函数被调用时,该参数会作为原函数运行时的this指向arg1, arg2, .... 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
箭头函数的this指向始终是指向的外层作用域。


混入技术


浅复制与深复制
虽然我们实现了对象的混入,但是,这种混入有一个缺点,那就是混入时如果对象的属性是一个引用类型的数据,例如是一个数组或者是一 个对象,那么只会发生浅复制,也就是说只会复制其引用
创建一个mixin()函数,该函数会对一一个对象的所有属性进行深度的复制

Let mixin = function(target,.. objects){
//首先遍历要混入的对象用objeft 来进行接收每一个要混 人的对象
for(const object of objects){
//要混入的必须是对象所以先进行一个 类型的判断
if(typeof object === 'object'){
//取出混入对象的每一个属性
for(const key of 0bject. keys (object)){
//如果属性所对应的值为对象继续递归调用mixin
if(typeof object[key] === ' object'){
target[key] = Array. isArray(object[key]) ? [] : {};
mixin(target [key] , object [key]);
}else{
//否则就直接混入到目标对象里面
0bject.ass ign(target , object);

}

posted @ 2019-08-11 21:54  风雨载明  阅读(197)  评论(0编辑  收藏  举报