JavaScript面向对象设计

2016-06-09  本文已影响39人  郝翔

参考资料:

疑问

{object Object}

创建对象

  1. Object构造函数
  2. 对象字面量

创建属性

定义单一属性

  1. 数据属性(默认可以直接创建或者使用Object.defineProperty()
  2. 访问器属性(必须使用Object.defineProperty())

数据属性

修改属性的默认特性

  • Object.defineProperty()(ECMAScript5)
  • 参数:接受三个参数,属性所在的对象,属性的名字,一个描述符对象,如不指定描述符对象,则除value外都为false
  var person = {};
  Object.defineProperty(person,"name",{
  writable: false,
  value: "haoxiang"
});
  alert(person.name); // haoxiang
  person.name = "haoqi";
  alert(person.name); // haoxiang

访问器属性

var book = {
  _year : 2015,
  edition: 1
}; // 定义了两个数据属性,其中的`_`用来标记只能通过对象方法访问到的属性
Object.defineProperty(book,"mouseyear",{
  get: function(){
    return "read";
  },
  set: function(){
    alert("write");
  }
});
alert(book.mouseyear);//read,读取属性会调用`get`函数
book.mouseyear = 200;//write,写入属性会调用`set`函数

来个复杂些的,书上说这个是使用访问器属性的常用方式,主要的特点是设置一个属性的值,会影响其他属性的变化,先提前留个印象

var book = {
  _year : 2004,
  edition: 1
}; //定义`book`对象,其中包含`_year`,`edition`数据属性
Object.defineProperty(book, "year",{
  get :function () {
    return this._year;
  },
  set :function (newValue) {
    if (newValue > 2004) {
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
});
//接着为`book`对象创建`year`访问器属性,访问器属性是没有`[[Value]]`特性的,它的值就是依靠get,set函数读取和写入
console.log(book.year);
//2004,这里我们使用`book.year`读取这个访问器属性,这个访问器属性会使用它的`get`函数,`return this._year`
book.year = 2005;
//为对象的访问器属性写入新值,这个值看起来作为了`set`函数的参数,这个传参过程让人有些看不懂,后续我会跟进
console.log(book._year);
//2005,由于之前使用了访问器属性的`set`函数,这个函数内部会把`this._year = newValue`,所以这里输出正常,是2005
alert(book.edition);
//2,由于之前使用了访问器属性的`set`函数,这个函数内部会把`this.edition += newValue - 2004;,所以这里输出正常,`edition`是2

定义多个属性

Object.defineProperties()
参数:接受两个对象参数,第一个对象为要添加或者修改属性的对象,第二个对象为需要在第一个对象中添加的属性

读取属性的特性

Object.getOwnPropertyDescriptor()
参数:接受两个参数,第一参数为属性所在的对象,第二个参数为要读取特性的属性
返回值:有返回值,返回值为一个对象,包含当前属性的所有特性
看代码

var num = {num1 : 1};// 定义一个对象,包含数据属性`num1`
var res = Object.getOwnPropertyDescriptor(num,"num1");// 使用这个方法,结果是包含属性所有特性的对象,放在res中
for( d in res){
  console.log(d);
}
//value
//writable
//enumerable
//configurable
//枚举属性的所有特性,也间接说明了如果字面量创造对象,包含的属性为数据属性,访问器属性必须通过方法来创建
{% endhighlight %}

### 构造函数模式
> - 创建已知函数,利用this和函数本身传参的特性
> - 之后使用new操作符
> - 通过构造函数模式创造的对象,会有一个`constructor属性`指向构造函数

#### 过程
```javascript
  function Person (name,age) {
    this.name = name;
    this.age = age;
  }
  var person1 = new Person("hao","22");
  console.log(person1);
  //Person {name: "hao", age: "22"}

new操作符的大致过程

  1. 创建一个新对象
  2. 将构造函数的作用域给新对象,(因此this就指向新对象)
  3. 执行构造函数内的代码(为新对象添加属性)
  4. 返回新对象

我大致模拟了这个过程,不一定可以保证必然是正确的,如果大家发现我的想法是错的,可以直接留言

function Person (name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;
}
var person1 = {}; //创建了一个新对象
person1.Person = Person;
console.log(person1.Person);
//将新对象的一个属性作为变量,将函数的指针(也就是函数名,函数的地址)赋给属性person,因此person1.person指向堆内存中的函数对象
person1.Person("hao",22,"student");//执行这个函数进行赋值
console.log(person1);//Object {name: "hao", age: 22, job: "student"}

下面这种的可能性貌似大些:

function Person (name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;
}
var o = {
};
Person.call(o,"hao",22,"student");
console.log(o);
//Object {name: "keneth", age: 22, job: "studenet"}

原型模式

上一篇下一篇

猜你喜欢

热点阅读