2016前端学习(二)

之前总结了基本类型的判断和检测,现在来总结下Javascript中对象的原型和继承

二、对象与原型

首先建立各一个简单的对象

1
2
3
4
5
6
7
8
var person = new Object();
person.name = 'tuzkiss';
person.age = 24;
person.job = 'Front-end developer';

person.sayHi = function () {
alert(this.name)
};

在ECMAScript中有两种属性,数据属性访问器属性

数据属性 : 包含一个数据值位置,在这个位置可以读取或者写入值。有4个特性
1、【Configurable】 : 表示是否通过delete删除属性, 是是否能修改属性的特性, 或者是否能把修改成访问器属性。默认为true。
2、【Enumerable】 : 表示能否通过for-in循环返回属性。默认为true。
3、【Writable】 : 表示能否修改属性的值。默认为true。
4、【Value】 : 包含这个属性的值。默认值为undefined。

如果要修改默认属性的特性的话,必须使用ECMAScript5中的Object.defineProperty()方法。这个方法介绍三个参数,属性所在的对象属性的名称一个描述符的对象。 描述符的属性是上面4种种的。

例如 :

1
2
3
4
5
6
7
8
9
var person = {};
Object.defineProperty(person, 'name', {
writable : false,
value : 'tuzkiss'
});

console.log(person.name); // tuzkiss
person.name = 'tom';
console.log(person.name); // tuzkiss

上述person对象中配置了writable为false,之后的修改都无法生效。

可以多次使用Object.defineProperty()方法修改同一个属性,但在把configurable特性设置为false之后就会有限制了。

访问器属性

访问器属性不包含数据值,包含一堆getter和setter函数。同样,访问器属性也拥有4个特性

1、【Configurabel】 : 表示能否通过delete删除属性重新定义属性,能否修改属性的特性,或者说修改成数据属性。默认值为true。
2、【Enumerable】 : 表示能否通过for-in循环返回属性。默认为true。
3、【Get】 : 在读取属性是调用的函数,默认为undefined。
4、【Set】 : 在写入属性是调用的函数,默认为undefined。

例如 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

var book = {
_year : 2004,
edition : 1
};

Object.defineProperty(book, 'year', {
get : function () {
return this._year;
},
set : function (newValue) {

if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});

book.year = 2005;
console.log(book.edition); // 2

以上代码创建了一个book对象,给它定义了两个默认的属性: _year和edition。然后使用Object.defineProperty()添加year属性,同时改写get和set方法。

当然 也可以同时创建多个属性。

那么,现在才进入正题 :

1、创建对象

工厂模式

例如,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function createPerson (name ,age, job) {
var o = new Object();

o.name = name;
o.age = age;
o.job = job;

o.sayHi = function () {
alert(this.name);
}

return o;
};

var tuzkiss = createPerson('tuzkiss', 24, 'FEer');

构造函数模式

例如:

1
2
3
4
5
6
7
8
9
10
11
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;

this.sayHi = function () {
alert(this.name);
}
};

var tuzkiss = new Person('tuzkiss', 24, 'FEer');

构造函数模式(Person)跟 工厂模式(createPerson)有以下区别之处:

  • 没有显式的创建对象
  • 直接降属性或方法付给了this对象
  • 没有return 语句

使用构造函数创建对象时实际经历4个步骤:
1、创建一个新的对象
2、将构造函数的作用域赋给新对象(所以this指向了这个新对象)
3、执行构造函数中的代码 (为这个新对象添加属性)
4、返回新对象

所以 :

1
2
3
tuzkiss.constructor === Person;  // true

tuzkiss instanceof Person; // true

原型模式

我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象。

例如:

1
2
3
4
5
6
7
8
9
10
11
function Person () {};

Person.prototype.name = 'tuzkiss';
Person.prototype.age = 24;
Person.prototype.job = 'FEer';
Person.prototype.sayHi = function () {
alert(this.name);
}

var tuzkiss = new Person();
tuzkiss.sayHi(); // 'tuzkiss'

2、理解原型