Javascript 不可不知的秘密 -- Class 与 面向对象

元气小坏坏 提交于 2019-11-27 13:23:16

1.类对象的创建方式

  • new 关键字,通过调用 constructor()方法来创建对象
  • {} 直接赋值,这种格式中,最后一个属性后面如果有逗号,对于ES5是忽略的,大部分的ES3也是忽略的,IE中会报错(赞一个)
  • Object.create(), es5

2. 类的属性

  • 属性特性
    • 可写(writable) : 可以设置,修改属性的数值
    • 可枚举(enumerable) : 可以通过 for/in 循环 返回该属性
    • 可配置(configurable) : 可以修改,删除属性本身的特性
  • 类对象的特性
    • 对象的原型prototype : 指向另外一个对象,本对象的属性继承自原型对象
    • 对象的类 class : 标志对象类型的字符串
    • 对象可扩展标记 extensible flag : 指明是否可以为对象添加新的属性(es5规范)
  • 对象类别、属性类别
    • 内置对象 (native object) 都是 ECMAScript规定的类,如Array,Function,Date,RegExp
    • 宿主对象(host object) , 是由 JS 解释器嵌入的宿主环境,比如浏览器定义的一些列DOM对象
    • 自定义对象(user-defined object) 是由 js代码创建的对象
    • 自有属性 (own property) 是直接在对象中定义的属性
    • 继承属性 (inherited property)实在对象的原型对象中定义的属性。

2.继承 与 prototype 原型

  • 什么是prototype

    • 每个Javascript类在定义的时候,会关联(继承) 另外一个对象(prototype),每个该类的对象在创建的时候,会从这个对象上来继承属性,这个对象就是prototype。
  • prototype 的一些特性

    • 通过关键字 new 和 构造函数创建对象的原型,就是构造函数的prototype所引用的对象

    • 所有通过JSON 直接量创建的对象共用同一个原型对象,且通过Object.prototype 可以获取到原型对象

    • 使用 new Object() 创建的对象的原型也是 Object.prototype

    • Object.prototype 对象没有自己的原型对象,其他的对象都直接或者间接的继承自Object.prototype 对象

    • prototype 也是一个对象,prototype 也具有自己的 prototype对象,所有的prototype 对象串联起来,形成一个可以访问到的作用域链,叫做原型链,原型链的结尾是Object.prototype

4. 属性的访问

  • 属性的getter,setter - 具有 getter,setter 的属性 是 accessor property; 普通的属性是 d> 这里输入引用文本ata property;
    • 通过 this.someAccessorProperty 访问 或者 赋值某个accessor property, 实际上调用的是对应的 getter,setter 方法
    • 只具备getter 属于只读属性;只具备setter属于只写属性,访问属性的数值返回undefined;同时具备setter,getter属于读写属性;两者都不具备属于普通属性
    • getter,setter 属于ES5 标准
    • getter,setter 的定义方法 : var obj = { x1:1, x2:2, get scale(){ return x2/x1; }, set scale(s){ this.x2 = x1 * s; } };
    • gettter, setter 属性的访问同正常属性,用 obj.prop 或者 obj['prop']
  • 属性的访问
    • 属性的描述信息:
      • 属性的可配置 configurable
      • 属性的可枚举 enumerable
      • 属性的可写 writable (accessor property 由 setter 决定)
      • 属性的值 value (accessor property 由 getter 决定)
    • ES5中对于属性描述信息(属性特性)的API:
      • Object.getOwnPropertyDescriptor(obj,prop) : 返回 {value:obj,writable:boolean,enumerable:boolean,configurable:boolean} --> 普通属性; {value:getterFunction,writable:setterFunction,enumerable:boolean,configurable:boolean} --> accessor property
      • Object.getPrototypeOf(obj) : 返回obj 的原型函数
      • Object.defineProperty(obj,prop,descriptor),例如Object.defineProperty({},'id',{value :1,writable:true,enumerable:true,configurable:true});
      • Object.defineProperties(obj,descriptorObj),Object.defineProperties({},{x:{value:1,writable:false,enumerable:true,configurable:false},y:{value:1,writable:false,enumerable:true,configurable:false}});
    • 对象特性对属性的影响:
      • extensible: 对象的可扩展性决定能否为对象添加新的属性
    • 属性的访问规则:
      • 如果对象不可扩展,不能添加新属性
      • 如果属性不可配置,不可通过defineProperty,defineProperties来修改属性描述符;如果是accessor property,不可更改setter,setter;如果是 data property,不能将可写性 由false改为true,但可以由true改为false;不可进行accessor property ,data property 之间的互转
      • 如果data property不可写,不可配置,那么不能修改它的值;如果只是不可写,但是可以配置,可以通过 defineProperty 来修改value的值
    • getter,setter,与旧式 API
      • _lookupGetter_()
      • _lookupSetter_()
      • _defineGetter_()
      • _defineSetter_()

5. 对象相关

  • 对象的特性
    • prototype
    • class 属性: 只能通过默认的 Object.toString() 方法来获取并截取字符串获得;对于重写了toString() 方法的类,需要间接调用Object.toString() 方法获取: Object.prototype.toString.call(obj).slice(8,-1);
    • extensible
      • Object.isExtensible()
      • Object.preventExtensions()
      • 一旦将对象转换为不可扩展的,就不能再更改了
      • 对象的封闭 : Object.seal()
      • 对象的冻结: Object.freeze()
  • _proto_
    • Mozilla 早期暴露出的 对象原型的引用方式,目前,IE,Opera不支持,具有兼容问题,支持ES5 的可以使用 Object.getPrototypeOf(), 或者 对象的 constructor 的属性来对应检测对象的原型函数

6. 对象的重写方法

  • toString()
  • toLocalString()
  • valueOf() : 执行类型转化的时候会用到
  • toJSON(): JSON.stringfy() 方法会调用
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!