美文网首页
第6章 面向对象的程序设计 (上)

第6章 面向对象的程序设计 (上)

作者: Shiki_思清 | 来源:发表于2020-04-22 01:04 被阅读0次

6.1 理解对象

1. 数据属性

包含 ConfigurableEnumerableWritableValue
分别代表 是否可操作是否可返回值for-in是否可重写具体值默认undefined

2. 访问器属性

包含 ConfigurableEnumerableGetSet
分别代表 是否可操作是否可返回值for-in读取调用函数写入调用函数

3.使用体现

1.Object.defineProperty()   // 定义一个对象
2.Object.defineProperties()   // 定义多个对象
3.Object.getOwnPropertyDescriptor() // 取得给定属性的描述符

6.2 创建对象

1. 工厂模式

function createPerson(name, age, job) {
  var o = new Object();
  o.name = name
  o.sayName = funtion() {
    alert(this.name);
  }
  return o;
}
var person1 = createPerson('Nicol',12, 'ali');
var person2 = createPerson('Greg',15, 'ten');

特点:解决了创建多个相似对象
缺点: 没有解决对象识别问题 => alert( person1 instanceof createPerson ) // false

2.构造函数模式

function Person(name, age, job) {
  this.name = name;
  this.sayName = function() {
    alert(this.name)
  }
 }
var person1 = new Person('Nic', 29, 'soft');
var person2 = new Person('SI', 21, 'MI');

特点: 1.使用new; 2.P大写; 3.构造函数的作用域赋给新对象;4.解决了对象识别问题
(alert( person1 instanceof Person ) // true)
缺点: 1. 如果不用new,则this指向window; 2. 构造函数中的函数在每个实例上都需要重新创建,造成资源浪费。

3.原型模式

function Person() {}
Person.prototype.name = 'Nic';
Person.prototype.age = '23';
Person.prototype.sayName = function () { alert(this.name) };
var person1 = new Person();
var person2 = new Person();
console.log(person1.sayName()) //'Nic'
console.log(person2.sayName()) //'Nic'
console.log(person1.sayName() === person2.sayName())  // true

特点: 1.Person.prototype.constructor 指向Person; 2. person1 指向 Person.prototype; 3.person1实例上没有sayName方法,根据原型链向上找到Person.prototype中有;4.hasOwnProperty()可判断实例peroson1上的属性,不能判断prototype上的属性;5. ’in' 能访问到就行;
缺点: 1. 虽然解决了方法共享问题,但制造出引用类型数据也同时共享的问题 ( friends: ['Shely', 'Court'] )

4. 组合使用构造函数模式和原型模式

function Person (name, age, job) {
  this.name = name;
  this.friends = ['Shily', 'Court']
}
Person.prototype = {
  constructor: Person;
  sayName: function () { alert( this.name ) }
}
person1.friends.push('Van') // 'Shily', 'Court', 'Van'
person2.friends // 'Shily', 'Court'

特点: 1.实例属性是构造函数中定义,而由所有实例共享的属性constructor和方法则是在原型中定义 2.往一个实例属性中添加,不会影响另一个实例中该属性值

5. 动态原型模式

function Person(name, age, job) {
  this.name = name
  ···
  if ( typeof this.sayName != "function") {
    Person.prototype.sayName = fucntion() { alert(this.name) }
  }
}

特点: 看起来比上面的4 工整许多,写在一个方法里

6. 寄生构造函数模式

特点: 比工厂函数 多了一个new 来创建实例;

7. 稳妥构造函数模式

不说了。

总结

构造函数P、原型P.p和实例p的关系: 每个构造函数都有一个原型对象(P中有P.p),原型对象都包含一个指向构造函数的指针(P.p -> P,也就是P.p 中的 constructor: P),而实例都包含一个指向原型对象的内部指针(p -> P.p)

相关文章

网友评论

      本文标题:第6章 面向对象的程序设计 (上)

      本文链接:https://www.haomeiwen.com/subject/mnhvihtx.html