看了阮一峰大神的博客,自己写了js面向对象这一部分的总结
js面向对象部分分为几个部分:
1.本文介绍面向对象–封装
2.面向对象–原型链
http://blog.youkuaiyun.com/github_34514750/article/details/51045708
3.面向对象–构造函数的继承
http://blog.youkuaiyun.com/github_34514750/article/details/51336839
4.面向对象–非构造函数的继承
http://blog.youkuaiyun.com/github_34514750/article/details/51337015
ECMAScript支持面向对象编程,但不使用类或者接口。对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体。在没有类的情况下,可以采用下列模式在创建对象。
1. 工厂模式
工厂模式的优点:
发明了一种函数,用函数来封装以特定接口创建对象的细节。
工厂模式的问题:
虽然解决了多个相似对象的问题,但却没有解决对象识别的问题。
工厂模式的语法
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("wanghuan",22,"software engineer");
var person2 = createPerson("shuguang",22,"army");
2. 构造函数模式
构造函数模式的优点:
自定义的构造函数意味着将来可以把它的实例标识为一种特定的类型,这正是构造函数模式胜过工厂模式的地方。
构造函数模式的语法
function Person (name,age,job) {//构造函数,习惯性的第一个字母大写
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}//其实有this对象在,根本不用在执行代码前把函数绑定到特定对象上边
}
var person1 = new Person("wanghuan",22,"software engineer");
var person2 = new Person("shuguang",22,"army");
构造函数模式的缺点:
构造函数主要问题就是每个方法都要在每个实例上重新创建一遍,这种方法创建函数,会导致不同的作用域链和标识符解析。
因此,用
function Person (name,age,job) {//构造函数,习惯性的第一个字母大写
this.name = name;
this.age = age;
this.job = job;
}
function sayName(){
alert(this.name);
}//把sayName()函数的定义转移到了构造函数外部,对象共享在全局作用域中定义的同一个函数
var person1 = new Person("wanghuan",22,"software engineer");
var person2 = new Person("shuguang",22,"army");
但还有缺点:
1. 全局作用域定义的函数每次被一个对象调用,全局作用域不是名副其实
2. 对象需要定义很多方法,要是全部都定义成全局函数,自定义的引用类型就丝毫无封装性可言。
3. 原型模式
缺点:所有属性的共享会导致所有实例默认一样的属性值,不合常理
创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向函数的原型对象。
每次读取某个对象的某个属性的时候,需要执行搜索:
1.搜索对象实例本身,在实例中找到给定名字的属性,则返回属性的值,使用delete属性可以删除实例属性。
2. 若没找到,则继续搜索指针指向的原型对象。
言外之意,对象实例本身的属性优先。
ps:用hasOwnProperty来判断属性是否存在于实例中或者原型中
此图为添加实例属性的情况:
原型模式的语法
function Person () {
}
Person.prototype.name = "wanghuan";
Person.prototype.age = "22";
Person.prototype.job = "software engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = "shuguang";
alert(person1.name);//shuguang---先搜索实例对象,就返回
alert(person1.hasOwnProperty("name"));//true
alert(person2.name);//wanghuan--原型对象属性返回
delete person1.name;//delete操作符删除实例属性
alert(person1.hasOwnProperty("name"));//false
alert(person1.name);//wanghuan--原型对象属性返回
原型模式更简单的语法
以对象字面量形式创建的新对象
function Person () {
}
Person.prototype = {
name:"wanghuan",
age : "22",
job : "software engineer",
sayName: function(){
alert(this.name);
}
};
4. 原型模式和构造函数模型的组合使用
//构造函数
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["a","b"];
}
//原型对象
Person.prototype = {
constructor:Person;
sayName:function(){
alert(this.name);
}
}
var person1 = new Person("wanghuan",22,"software engineer");
var person2 = new Person("shuguang",22,"army");
person2.friends.push("c");
alert(person1.friends);//a,b
alert(person2.friends);//a,b,c
alert(person1.sayName === person2.sayName);//true
//说明两者的函数指针相同