面向对象

96次阅读

共计 2386 个字符,预计需要花费 6 分钟才能阅读完成。

面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象
创建对象
虽然 Object 构造函数或者对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量重复代码 (为什么或产生大量重复的代码?)。
工厂模式
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);

工厂模式的特点:解决了创建多个相似对象的问题,但却没有解决对象识别的问题 (即怎么知道一个对象的类型);
构造函数模式
构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。这个做法借鉴自其他 OO 语言,主要是为了区别于 ECMAScript 中的其他函数;因为构造函数本身也是函数,只不过可以用来创建对象而已。

function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);

要创建 Person 的新实例,必须使用 new 操作符。这中方式调用构造函数实际上回会经历 4 个步骤

创建一个对象
将构造函数的作用域赋给新对象 (因此 this 就指向了这个新对象)
执行构造函数中的代码 (为这个新对象添加属性)
返回新对象

缺点: 每个方法都要在每个实例上重新创建一遍。
原型模式
每一个函数都有一个 prototype(原型) 属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以有特定类型的所有实例共享的属性和方法。
function Person(){
}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //”Nicholas”

var person2 = new Person();

person2.sayName(); //”Nicholas”
alert(person1.sayName == person2.sayName); //true

新对象的这些属性和方法是由所有实例共享的。换句话说,person1 和 person2 访问的都是同一组属性和同一个 sayName() 函数
理解原型对象
构造函数、原型和实例的关系:每个构造函数都有一个原型对象(prototype 属性),原型对象都包含一个指向构造函数的指针(constructor(构造函数) 属性),而实例有包含一个指向原型对象的内部指针([[Prototype]]、Firefox、Safari 和 Chrome 在每个对象上都支持一个属性__proto__)

更简单的原型语法
function Person(){
}
Person.prototype = {
constructor : Person, //
name : “Nicholas”,
age : 29,
job: “Software Engineer”,
sayName : function () {
alert(this.name);
}
};
本质上完全重写了默认的 prototype 对象,因此 constructor 属性也就变成了新对象的 constructor 属性(指向 Object 构造函数),不再指向 Person 函数。所以需要手动设置 constructor 属性,并将它的值设置为 Person,确保通过该属性能够访问到适当的值。
原型与 in 操作符
原型的动态性
原生对象的原型
原型对象的问题
缺点:

因为省略了为构造函数传递初始化参数这一环节,结果所有在默认情况下都将取得相同的属性值
最大问题是由其共享的本性所导致的。

原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说的过去,毕竟(如前面的例子所示),通过在实例上添加同一个同名属性,可以隐藏在原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出了。
function Person(){
}
Person.prototype = {
constructor: Person,
name : “Nicholas”,
age : 29,
job : “Software Engineer”,
friends : [“Shelby”, “Court”],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push(“Van”);
alert(person1.friends); //”Shelby,Court,Van”
alert(person2.friends); //”Shelby,Court,Van”
alert(person1.friends === person2.friends); //true

正文完
 0