面向对象的JavaScript
面向对象的JavaScript
对象属性
数据属性
- configurable: 表示能否通过delete删除属性从而重新定义属性,或能否将属性修改为访问器属性
- enumberable: 表示能否通过for-in循环返回属性
- writeable: 表示能否修改属性的值
- value: 包含这个属性的数据值,读属性的时候从这个位置读;写入属性值的时候,把新值保存在这个位置
object.defineProperty()
通过defineproperty()来修改属性默认的特性,接收三个参数(属性所在的对象,属性的名字,一个描述符对象)
var person = {};
Object.defineproperty(person,"name",{
writeable: false;
value: "fan"
});
console.log(person.name) //fan
person.name = "dan";
console.log(person.name) //fan
访问器属性
- configurable: 表示能否通过delete删除属性从而重新定义属性,或者能否将属性修改为数据属性
- enumberable: 表示能否通过for-in循环返回属性
- get: 读取属性时调用的函数
- set: 写入属性时调用的函数
创建对象
工厂模式
function person(name,age,sex) {
var o = new Object();
o.name = name;
o.age = age;
o.sex = sex;
return o;
}
var person1 = preson("fan",22,"male");
- 优点:解决了重复创建多个相似对象的问题
- 缺点:无法确定对象的类型
构造函数模式
function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
var person2 = new Person("dan",20,"male")
//new的过程
// 1. 创建一个新的对象
// 2. 将构造函数的作用域赋给新的对象(即this指向了新的对象)
// 3. 执行构造函数的代码(为新的对象添加属性)
// 4. 返回新的对象
- 可以确定确定对象的类型
- 每个方法都要在每个实例上重新创建一遍
原型模式
function Person() {
}
Person.prototype.name = 'fan';
Person.prototype.age = 25;
Person.prototype.sayName = function() {
alert(this.name)
}
// 更简洁的原型语法
Person.prototype = {
name: 'fan',
age: 25,
sayName: function() {
alert(this.name);
}
}
var person1 = new Person();
person1.sayName() // 'fan'
person1.name = 'wen';
person1.sayName() // 'wen' => 来自实例
var person2 = new Person();
person2.sayName() // 'fan' => 来自原型
组合
// 组合使用构造模式和原型模式
function Person() {
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name)
}
}
继承
原型链继承
function SuperType() {
this.colors = ['red', 'black', 'green'];
}
function SubType() {
}
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push('blue');
var instance2 = new SubType();
// 问题:影响其他的实例
console.log(instance2.colors); // "red, black, green, blue"
构造函数继承
function SuperType() {
this.colors = ['red', 'black', 'green'];
}
function SubType() {
// 继承了superType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push('blue');
var instance2 = new SubType();
// 不会影响其他的实例
console.log(instance2.colors); // "red, black, green"
组合继承
// 组合继承
function SuperType() {
this.colors = ['red', 'black', 'green'];
this.name = name;
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(name, age) {
// 继承属性
SuperType.call(this, name); // 第二次调用SuperType()
this.age = age;
}
// 继承方法
SubType.prototype = new SuperType(); // 第一次调用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
console.log(this.age);
}
var instance1 = new SubType('fan', 25);
instance1.colors.push('blue');
console.log(instance1.colors); // "red, black, green, blue"
instance1.sayName(); // 'fan'
instance1.sayAge(); // '25'
var instance2 = new SubType('dan', 24);
console.log(instance2.colors); // "red, black, green"
instance2.sayName(); // 'dan'
instance2.sayAge(); // 24
- 缺点:调用两次超类型构造函数
ES6
class Point {
}
class ColorPoint extends Point{
constructor(x, y, color) {
//调用父类的constructor
super(x, y);
this.color = color;
}
toString() {
//调用父类的toString()
return this.color + ' ' + super.toString();
}
}