JS基础 - 类和对象

创建对象

  • 对象直接量 
    对象直接量就是名/值对数据格式,见下面代码
  • var obj = {
        prop1: 1,
        prop2: '属性'
    }
  • new关键字 
    "new [类名]"的方式能返回类的实例化对象, 类可以是构造函数名,也可以类名(ES2015+)
  1. var Example = function() {
        this.prop1 = 1;
        this.prop2 = '属性';
    };
    var obj = new Example();
    class Example {
       consturctor() {
           this.prop1 = 1;
           this.prop2 = '属性';
       }
    }
    var obj = new Example();
  • create关键字 
    这种方式可以指定属性的特性(property attribute),见下面代码(ES5+)
  1. var Example = function() {};
    Object.create(Example.prototype, {
       prop1: {
           value: 1
       },
       prop2: {
           value: '属性'
       }
    }

     

原型(prototype)

概念

  1. 函数对象都有prototype属性。
  2. prototype是一个对象,函数用于实例化后,每个实例化的对象,都从这个prototype对象继承属性。
  3. prototype对象的属性的变化,会影响已经实例化的继承这个prototype的对象。
  4. prototype有一个不可枚举的constructor属性,为当前prototype对应的构造函数,但并不意味着prototype对象是由这个constructor构造函数实例化而来。

ES2015之前的版本,类的继承就是通过prototype的继承特性来实现的,下面是一个类继承的例子: 
注:SuperClass为父类,SubClass为子类。

  1. var SuperClass = function() {};
    var inherit = function(superClass) {
       var EmptyClass = function() {};
       EmptyClass.prototype = superClass.prototype;
       var SubClass = function() {}
       SubClass.prototype = new EmptyClass();
       SubClass.prototype.constructor = SubClass;
    }
    var SubClass = inherit(SuperClass);

原型链(prototype chain)

因每个对象都有对应的原型对象,而原型对象也是个对象,这样它也有自己的原型对象,这种链式关系就形成了一个原型链。

有两种方式获取一个实例化对象obj的prototype对象。 
方式一:

  1. Object.getPrototypeOf(obj)

方式二:

  1. obj.__proto__

确定对象所关联的原型对象的规则是: 
1) 先看对象是由哪个构造函数实例化而来,构造函数的prototype属性就是这个原型对象了。 
2) 如果对象是一个函数(类)对象,找到这个函数(类)从哪个函数(类)继承而来,被继承的函数(类)对象的prototype属性就是这个原型对象。 
3) 如果对象是一个构造函数的prototype属性,先按第一条规则来确定,如果无法确定这个对象是由哪个构造函数实例化而来,再看是否能确定prototype对应的构造函数是从哪个构造函数所继承而来,如能确定,这个被继承的构造函数对象的prototype属性就是这个原型对象。 
4) 默认的构造函数是Object,按构造函数的继承关系,最终也会找到最上层的构造函数Object,那么原型对象也就是Object.prototype。 
5) Object.prototype对象所对应的原型对象是null。

根据上面的规则,看几个原型链的例子: 
注:Example是一个自定义类,obj是Example的实例对象。 
1) obj –> Example.prototype –> Object.prototype –> null 
2) Example–> Function.prototype –> Object.prototype –> null 
3) Object –> Function.prototype –> Object.prototype –> null 
4) Function –> Object.prototype –> null

 

对象属性

属性特性(property attribute)

从ES5开始,对象属性除了名字和值之外,还有一些其他的特性(property attribute),可以通过Object.getOwnPropertyDescriptor和Object.defineProperty这两个方法来读取或设置对象的属性特性:

  1. 可枚举(enumerable):是否能通过for/in遍历对象,访问到该属性。
  2. 可写(writable):是否能修改属性的值。当一个原型对象的属性a的writable为false,且这个原型对象的实例对象也有属性a时,只有原型对象的属性a受writable为false的影响而不能修改,但当继承这个原型对象的实例对象没有属性a,则会受原型对象writable为false的影响,而无法为实例对象赋值a属性。
  3. 可配置(configurable):是否能删除属性,或是否能修改属性的特性。一旦将configurable设置为false,将不能再调用Object.defineProperty对属性的行为进行修改(将enumerable/writable修改为false除外)。

属性定义

  • 直接设置
  1. obj.prop1 = 1;
    obj['prop2'] = '属性';
  • set/get
  1. obj = {
       get prop1() {
            return this.prop1;    
       },
       set prop1(val) {
           this.prop1 = val; 
       }    
    }
  • defineProperty
  1. Object.defineProperty(obj, 'prop1', {
       value: 1,
       enumerable: true,
       writable: true,
       configurable: true
    }
    Object.defineProperties(obj, {
       prop1: {
           value: 1
       },
       prop2: {
           value: '属性'
       }
    }

属性访问

  • 检测属性 
    in:检测自有和继承属性 
    hasOwnProperty:检测自有属性 
    propertyIsEnumerable:检测自有可枚举属性

  • 遍历属性 
    for - in:遍历自有和继承的可枚举属性 
    Object.getOwnPropertyNames:获取自有全部属性 
    Object.keys:获取自有的可枚举属性

属性删除

delete obj.prop1,可以解除属性prop1与对象obj的关联。 
delete关键字,只能删除自有属性(要删除继承属性需要在prototype上操作)。

posted @ 2017-03-08 16:37  蓼椮  阅读(167)  评论(0编辑  收藏  举报