面向对象

面向对象是现实的抽象方式,用对象来描述事务,更有利于我们将现实的事物抽离成代码的数据结构

创建对象的方式

new Object()

  1. var obj=new Object();
  2. obj.name='rv';
  3. obj.age=20;

字面量形式

  1. var obj={
  2. name:'rv',
  3. age:20
  4. };

工厂模式

缺陷:

  • 无法准确判断对象类型
  1. function createPerson(name,age){
  2. var p={};
  3. p.name=name;
  4. p.age=age;
  5. p.running=function(){
  6. console.log(this.name+"在跑步")
  7. }
  8. return p;
  9. }

构造函数

  1. /* 构造函数调用方式,不加小括号则为不传参调用 */
  2. var foo1=new Person;
  3. var foo2=new Person('rv',20);
  4. function Person(name,age){
  5. this.name=name;
  6. this.age=age;
  7. }
  8. Person.prototype.runing=function(){
  9. console.log(this.name+"在跑步");
  10. }

对象属性描述符

Object.defineProperty()

  1. Object.defineProperty(obj,prop,descriptor)
  2. /*
  3. obj:对象
  4. prop:需定义或修改的属性名或Symbol
  5. descriptor:属性描述符
  6. */

属性描述符

  • 数据属性描述符
  • 存取属性描述符

1. 数据属性描述符

[[Configurable]]

表示属性是否可以通过delete删除属性,是否可以修改它的特性

  • 当我们直接在对象上定义属性时,默认[[Configurable]]为true
  • 当我们通过属性描述符定义一个属性时,默认[[Configurable]]为false

[[Enumerable]]

表示属性是否可以通过for-in或者Object.keys()返回该属性

  • 当我们直接在对象上定义属性时,默认[[Enumerable]]为true
  • 当我们通过属性描述符定义一个属性时,默认[[Enumerable]]为false

[[Writable]]

表示是否可以修改属性值

  • 当我们直接在对象上定义属性时,默认[[Writable]]为true
  • 当我们通过属性描述符定义一个属性时,默认[[Writable]]为false

[[value]]

表示属性的value值

  • 默认情况下这个值为undefined
  1. var obj={
  2. name:'rv'
  3. }
  4. Object.defineProperty(obj,'age',{
  5. value:20,
  6. configurable:false,
  7. enumerable:false,
  8. writable:true
  9. })

2. 存取属性描述符

使用场景

  1. 隐藏某一个私有属性,不希望直接被外界使用和赋值
  2. 截获某个属性的获取和设置的过程

[[Configurable]]

表示属性是否可以通过delete删除属性,是否可以修改它的特性

  • 当我们直接在对象上定义属性时,默认[[Configurable]]为true
  • 当我们通过属性描述符定义一个属性时,默认[[Configurable]]为false

[[Enumerable]]

表示属性是否可以通过for-in或者Object.keys()返回该属性

  • 当我们直接在对象上定义属性时,默认[[Enumerable]]为true
  • 当我们通过属性描述符定义一个属性时,默认[[Enumerable]]为false

[[get]]

获取属性时会触发的函数

  • 默认为undefined

[[set]]

获取属性时会触发的函数

  • 默认为undefined
  1. var obj={name:'rv'}
  2. Object.defineProperty(obj,'age',{
  3. configurable:false,
  4. enumerable:false,
  5. get:function(){
  6. return this._age;
  7. },
  8. set:function(value){
  9. this._age=value;
  10. }
  11. })

Object.defineProperties()

  1. var obj={}
  2. Object.defineProperties(obj,{
  3. name:{
  4. configurable:false,
  5. value:'rv'
  6. },
  7. age:{
  8. enumerable:true,
  9. get:function(){
  10. return this._age;
  11. },
  12. set:function(value){
  13. this._age=value;
  14. }
  15. }
  16. })

Object.getOwnPropertyDescriptor(),Object.getOwnPropertyDescriptors()

  1. /* 获取单个属性描述符 */
  2. var obj={name:'rv'}
  3. Object.getOwnPropertyDescriptor(obj,'name');
  4. /* 获取所有属性描述符 */
  5. Object.getOwnPropertyDescriptors(obj);

Object.preventExtensions()

  1. /* 禁止对象添加新的属性 */
  2. Object.preventExtensions(obj);

Object.seal()

  1. /* 禁止对象新增/删除属性,不能修改属性配置,也影响__proto__的属性值不可修改 */
  2. Object.seal(obj);

Object.freeze()

  1. /* 冻结对象中的现有属性值是不可变的 */
  2. Object.freeze(obj);

new操作符调用过程

  1. 在内存中创建一个新对象
  2. 这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性
  3. 构造函数内部的this指向创建出来的新对性
  4. 执行函数的内部代码
  5. 如果构造函数没有返回非空对象,则返回创建出来的新对象