js中的oop(一)

1.什么是对象?

由属性组成的无序集合(n个键值对)。

2.数据类型分两类:

原始类型:undefined,null,boolean,string,number
object类型:function,array,date,regexp

3.对象结构:
  1. 对象属性;
  2. 属性特征;
  • writable是否可写的
  • enumerable是否可枚举的
  • configurable是否可重置的
  • getter ,setter
  1. proto对象的原型;
  • 指向另外一个对象,本对象属性继承自它的原型对像
  1. extensible对象的扩展标记;
  • 是否允许向该对象添加新属性
4.创建对象&原型链(查找某个属性或方法根据原型链自下向上):

I.对象直接量:var obj={} ;

  • obj.prototype-->Object.prototype-->null(原型链末端)

II.new函数构造器: var obj = new Foo();

  • 新创建的对象的原型指向构造器的原型;
  • obj.prototype--->Foo.prototype-->Object.prototype-->null

III.var obj = Object.create({x:1});

  • Object.create会返回一个新对象,并且该对象会执行传入的那个参数对象
  • obj.prototype--->{x:1}.prototype-->Object.prototype-->null

V.var obj = Object.create(null);

  • obj.prototype=null//>obj.prototype-->null
5.对象的proto的内置属性
  • JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。
var zjh = new person(‘zhangjiahao’);  
zjh.getName(); //zhangjiahao

以上面的例子为例:

console.log(zjh.__proto__ === person.prototype) //true
  • person.prototype对象也有proto属性,它指向创建它的函数对象(Object)的prototype
console.log(person.prototype.__proto__ === Object.prototype) //true
  • Object.prototype对象也有proto属性,但它比较特殊,为null
console.log(Object.prototype.__proto__) //null
  • 我们把这个有proto串起来的直到Object.prototype.proto为null的链叫做原型链。
js中的oop(一)_第1张图片
原型链
6.属性操作

6.1. 读写对象属性

  • obj.x / obj["x"]

6.2. 删除属性

  • delete只能删除自有属性
    delete obj.z//true
    delete obj['z']//true

6.3. 获取某个对象某个属性的描述对象

  • var decriptor=Object.getOwnPropertyDescriptor(Object,'prototype');
    //{value: {…}, writable: false, enumerable: false, configurable: false}

6.4. 检测属性归属

  • 'z' in obj //true可以便利自有属性以及继承属性
  • obj.hasOwnProperty('z'); //true 查找自有属性

6.5. 枚举属性

  • obj.propertyIsEnumerable('legs');//true是否可以枚举
  • for in 所遍历出来属性就是枚举性

6.6. 自定义属性

  • 注意:通过对象设置的属性默认属性描述都是true,而defineProperty创建的属性默认是false;
    Object.defineProperty(cat,'price',{enumerable:false,value:1000});
    cat.hasOwnProperty('price')//true
    cat.propertyIsEnumerable('price')//false
    

6.7. 实例理解

  • 遍历可枚举属性:
    var o = {x:1,y:2,z:3};
    var key;
    for (key in o){
        console.log(key);//x,y,z
    }
    
  • 遍历继承属性:
    var obj = Object.create(o);
    obj.a = 4;
    var key;
    for (key in obj){
        console.log(key);//a,x,y,z
    }
    
  • 仅遍历自有属性:
    var obj = Object.create(o);
    obj.a = 4;
    var key;
    for (key in obj){
       if(obj.hasOwnProperty(key)){
           console.log(key);//a
       }
    }
    

6.8. 另外一种读写属性的方式(getter/setter方法):

var man = {
    name: 'wangjie',
    weibo: '@evrygo',
    get age() {
        return new Date().getFullYear() - 1992;
    },
    set age(val) {
        console.log("Age can't be set to" + val);
    }
}
//访问age属性,就去调用getter方法
console.log(man.age); //27
//设置属性,就去调用setter方法
man.age = 100; //Age can't be set to 100
改进:
var man = {
    name: 'wangjie',
    weibo: '@evrygo',
    $age: null, //属性名前面加$ ,表示这个变量是私有
    get age() {
        if (this.$age == undefined) { //判断 $age是null或者undefined
            return new Date().getFullYear() - 1991;
        } else {
            return this.$age;
        }
    },
    set age(val) {
        val = +val; //va前面加一个一元操作符,为了得到数字;
        if (!isNaN(val) && val > 0 && val < 150) { //val不是NaN并且大于0小于150
            this.$age = +val;
        } else {
            throw new Eroor('Incorrect val = ' + val);
        }
    }
}  

6.9. 属性操作实例

  • 注意:
    给对象属性赋值,如果这个属性不是getter方法,赋值可以成功;
    但是属性是getter或者setter方法,就赋值不成功。
function foo() {} //创建一个空的函数对象
//给它的prototype对象添加属性z,并给它一个getter方法
Object.defineProperty(foo.prototype, 'z', {
    get: function () {
        return 1;
    }
});
//利用它创建一个对象
var obj = new foo();
obj.prototype-- - > foo.prototype-- - > 后续
obj.z; //1
obj.z = 10;
obj.z; //still 1
  • 如何给属性是getter或者setter方法,还要在obj这个对象上将这个属性赋值
Object.defineProperty(obj, 'z', {
   value: 100,
   configurable: true
});
obj.z; //100;
delete obj.z;
obj.z; //back to 1     
  • 总结实例
var o = {};
Object.defineProperty(o, 'x', {value: 1}); //writable=false,configurable=false;
var obj = Object.create(o);
obj.x; //1
obj.x = 200; //writable=false
obj.x; //still 1

Object.defineProperty(o, 'x', {
    writable: true,
    configurable: true,
    value: 100
});
obj.x; //100
obj.x = 500;
obj.x; //500

6.10. 属性描述符操作

  • 属性描述符控制某些属性操作权限:
    configurable:能否使用delete、能否修改属性描述符、或能否修改访问器属性、能否通过delete删除属性从而重新定义属性(Object.defineProperty)
    enumerable:对象属性是否可通过for-in循环
    writable:对象属性是否可修改
    value:对象属性的默认值
  • 属性特性获取以及设置
    • 显示某个对象的某一个属性的所有属性特性:
      Object.getOwnPropertyDescriptor({
         pro: true
      }, 'pro');
      Object{value:"true,writable:true,enumarable:true,configurable:truye"}
      
    • 注意:configurable控制这其他属性标签是否可改,还有控制属性是否delete
      实例1:
      var person = {};
      Object.defineProperty(person, 'name', {
         configurable: false,
         writable: false,
         enumarable: true,
         value: "evrygo"
      });
      person.name //evrygo
      person.name = 1;
      person.name; //still evrygo
      delete person.name; //false
      
      实例2:
      Object.defineProperty(person, 'type', {
        configurable: true,
        writable: true,
        enumarable: false,
        value: "Object"
      });
      //获取对象上所有属性名
      Object.keys(person); //["name"]
      //因为type为enumarable: false
      
  • 给某个对象的设置多个属性的属性特性
    Object.defineProperties(person, { //没有写的属性特性默认为false
      title: {
          value: 'fe',
          enumarable: true
      },
      corp: {
          value: 'ba',
          enumarable: true
      },
      salary: {
          value: 50000,
          enumarable: true,
          writable: true
      },
      luck: {
          get: function () {
              return Math.random() > 0.5
                  ? 'good'
                  : 'bad';
          }
      },
      promote: {
          set: function (level) {
              this.salary *= (1 + level * 0.1);
          }
      }
    });
    person.salary; //50000
    person.promote = 2; 
    person.salary; //60000
    

你可能感兴趣的:(js中的oop(一))