JavaScript面向对象设计

参考资料:

疑问

{object Object}

创建对象

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

创建属性

定义单一属性

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

数据属性

  • 数据属性包含一个数据值的位置,在这个位置进行读取和写入值
  • 数据属性包含多个描述其行为的特性(Configurable,Enumerable,Writable,Vlaue)

修改属性的默认特性

  • 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

访问器属性

  • 访问器属性不包含数据值,这类属性包含一对函数(getter,setter)
  • 在读取访问器属性时,会调用getter,写入时,会调用setter([[Configurable]],[[Enumerable]],[[get]],[[set]])
  • 访问器的属性不可以直接进行定义,必须使用Object.defineProperty()定义
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"}

原型模式

  • 函数的prototype属性和原型对象的constructor属性: 函数内部会有prototype属性,这个属性指向保存着所有实例共享的属性和方法的对象,叫做函数的原型对象,在默认情况下,所有的
    原型对象都会获得constructor属性,这个属性包含一个指向prototype属性所在函数的指针。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容