关于javaScript面向对象

数据属性

包含一个数据值的位置,可以进行读写操作,有四个描述行为的特性,默认值都为true

  • [[Configurable]]:表示能否通过delete删除属性而重新定义属性。能否修改属性的特性,或者能否把属性修改为访问器属性,一旦改为false,就无法改回true
  • [[Enumerable]]:表示能否通过for-in循环返回属性
  • [[Writable]]:表示能否修改属性的值
  • [[Value]]:表示包含这个属性的数据值。读取属性时,从这个位置读;写入新的属性值时,把新值赋在这个位置,默认值为undefined

注意:

  1. 要修改这些属性,必须通过Object.defineProperty( )方法,此方法接收3个参数:属性所在的对象、属性的名字、一个描述符对象(描述符对象的属性必须是:conifgurable、enumerable、writable、value中的一个或多个值)
  2. 在调用object.defineProperty( )方法时,不指定值,那么configurable等四个值都默认为false

访问器属性

可以理解为计算属性,在读取和写入前进行一定的数据或逻辑处理

  • [[Configurable]]:与数据属性描述相同
  • [[Enumerable]]:与数据属性描述相同
  • [[Get]]:在读取属性时调用的函数。默认值为undefined
  • [[Set]]:在写入属性时调用。默认值为undefined

注意:

  1. 访问器不能直接定义,必须使用Object.defineProperty( )来定义
  2. 可以使用Object.definedProperties( )来定义多个属性,接收两个参数:目标对象,目标对象需要添加或修改的属性(以对象包裹对象的形式创建)
  3. Object.getOwnPropertyDescriptor( ):可以取得给定属性的描述符。接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是一个对象,如果是访问器属性,这个对象的属性有configurable、enumerable、get、set;如果是数据属性则有configurable、enumerable、writable、value

对象方法

  • keys( ):可以取得对象上所有可枚举的实例属性(不包括继承属性),参数为一个对象,返回值为所有可枚举属性的数组
  • getOwnPropertyNames( ):参数为一个对象,返回所有的实例属性(无论是否可枚举)

对象相关

  • 原型与in操作符
    单独使用时:'属性名' in 实例对象;如果该对象访问此属性名(无论在自身还是在原型中)都返回ture,否则返回false
    使用for in时,返回的是所有能够通过对象访问的、无论属性是否可枚举的(enumerated),其中包含实例中的属性,也包含存在于原型的属性
  • 使用对象字面量方法重写原型对象
    等同于以对象字面量形式创建新对象,虽然结果相同,但constructor属性却不再指向原函数了(改为指向Object对象),尽管使用instanceof( )仍能返回true,但通过constructor已经无法确定对象类型,所以在重写时,应将constructor指回原来的对象
    实例中的指针,仅指向原型,不指向构造函数,当我们把原型修改为另一个对象时,就相当于切断了构造函数与最初原型的关系
    原型对象的问题:
    在原型对象中添加了引用类型的数据时,一旦修改里面的值,那么将会影响所有实例

创建对象

  • 使用Object构造函数创建对象
    缺点:使用同一个接口创建很多对象,会产生大量的重复代码
  • 使用工厂模式创建对象
    优点:解决了创建多个类似对象的问题
    缺点:创建出的对象无法识别是哪一个对象类型
  • 使用构造函数模式创建对象
    特点:没有显示的创建对象
               直接将属性赋给了this对象(作用域对象)
               没有return语句
               使用new操作符创建对象,其new操作符执行过程中会经历以下过程
               1.创建一个新的对象
               2.将构造函数的作用域赋给新对象(this就指向了这个新对象)
               3.执行构造函数中的代码(为此对象添加属性)
               4.返回新对象
    优点:解决了创建多个类似对象的问题,对象识别问题
    缺点:当创建的对象具有方法时,每创建一个对象就会新创建一个方法的实例对象,即使它们的作用一样
    解决方法:
            1.使用指向全局方法的函数,但在全局作用域中定义的函数实际上只能被某个对象调用,如果对象需要定义很多方法,那么就要定义很多全局函数,那么自定义的引用类型就无封装性可言了,因为谁都可以调用
            2.在构造函数的prototype对象中添加这些方法,就解决了上面每创建一个对象就会创建一个方法实例对象的问题,也解决了其他对象都能调用此方法的问题了
  • 原型模式
    创建的每一个函数都有prototype(原型)属性(对于创建出来的实例为[[prototype]]或__proto__),这个属性是一个指针,此对象可以由特定类型的所有实例共享的属性和方法
    实例对象中的__proto__指向创建此对象的构造函数的原型对象,继承的属性等,与此对象的构造函数没有关系,只与此对象的构造函数的原型对象有关系
    使用isPrototypeOf( )函数可以确定实例对象是否是构造函数创建出来的,存在__proto__这个联系。其语法为:构造函数.prototype.isPrototypeOf(实例对象)
    使用Object.getPrototypeOf(实例对象):返回实例对象的原型对象
    如果实例对象中的属性、方法,与该实例对象的__proto__对象的属性和方法名相同,那么当访问这些属性、方法的时候,将访问到实例对象中对应的属性、方法,但继承而来的也不会被覆盖掉,只是被屏蔽掉而已,如果将同名的属性设置为null也不会恢复指向原型的连接,只有使用delete操作符才能完全删除此实例属性(此特性与查找对象属性根据原型链来查找有关)
  • 组合使用构造函数模式和原型模式
    构造函数用于定义实例属性,而原型模式用于定义方法和共享属性
  • 动态原型模式
    将所有信息都放入构造函数中,在通过构造函数初始化原型时,又保持了构造函数和原型的优点(通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型),但不能再去使用对象字面量的方法重写原型对象,instanceof可以确定它的类型
  • 寄生构造函数模式
    创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后在返回新创建的对象。除了使用new操作符并把使用的包装函数叫做构造函数外,其他的与工厂模式一模一样。构造函数在不返回值的情况下,默认返回新对象实例。通过构造函数的末尾添加return,可以重写调用构造函数时返回的值。主要用于在特殊情况下未对象创造构造函数。比如许要创建一个具有额外方法的数组,由于不能直接修改Array构造函数,那么可以使用这个模式来创建此对象。其中返回的对象与构造函数或者与构造函数的原型属性之间没有关系,所以不能使用istanceof来确定对象类型
  • 稳妥构造函数模式
    稳妥对象指的是没有公共属性,而且其方法也不引用this对象。适合在一些安全环境中或者防止数据被其他应用程序改动时使用。稳妥构造函数遵循与寄生构造函数类似的模式,但有两点不同:一是新创建的对象实例不是使用this,二是不使用new操作符调用构造函数(使用的是函数正常调用形式),同样也不能使用instanceof方法确定对象类型

继承

ECMAScript中的函数没有签名,所以无法实现接口继承,只支持实现继承(继承实际的方法),实现继承主要是依靠原型链来实现的,使用instatnceof或isPrototypeOf可以检测视力原型链中是否有此原型

使用继承的几种方式

  • 借用构造函数(伪造对象或经典继承)
    在子类型构造函数的内部调用超类型构造函数,使用call( )或apply( )方法传入子类型对象,这样可以实现每个实例都具有自己的私有属性或方法。相对于原型链来说,借用构造函数可以在子类型构造函数中向超类型构造函数传递参数
    缺点:方法都在构造函数中定义,无法进行复用。而且在超类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型只能使用构造函数模式
  • 组合继承(伪经典继承)
    指的是将原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,通过借用构造荤素来实现对实例属性的继承,这样既在原型上定义方法实现了函数的复用,又实现了每个实例都有自己的属性。instanceof和isPrototypeOf能够识别组合继承创建的对象
  • 原型继承
    没有严格意义上的构造函数,借助原型基于已有的对象创建新对象。即在函数中创建一个临时的构造函数,并将传入的对象作为此构造函数的原型,最后在return出创建的对象(使用new操作符)
    ECMAScript新增Object.create( )方法规范化了原型继承。可接受两个参数:一个作用新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。在传入一个参数时,Object.create( )与Object( )行为相同,在传入两个参数时:第二个参数格式与Object.defineProperties( )方法格式相同,每个属性都是通过自己的描述符定义的。这种方式指定的任何属性都会覆盖原型对象的同名属性
  • 寄生式继承
    创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再返回对象。寄生式继承不能做到函数的复用。在主要考虑对象而不是自定义类型和构造函数下,可以使用此方式
  • 寄生组合继承
    借用构造函数来继承属性,通过原型链的形式来继承方法;本质上就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型
    javaScript是通过原型链实现继承,原型丽娜的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值