javascript 学习笔记之面向对象编程

ECMA-262 把对象定义为:'无序属性的集合,其属性可以包含基本值,对象或者函数'。(参考资料javascript高级程序设计-红宝石)
对象特殊属性:数据属性和访问器属性
1)数据属性:
[Configurable]-是否可删除  [Enumerable]-是否可枚举for in  [Writable]-是否可写  [value]值
要修改默认属性必须使用defineProperty(Object,name,descriptor)方法
例如:
var Person = {
    name:"john",
    age:"20",
    job:"student",
    sayName: function(){
        alert(this.name);
    }

}
Object.defineProperty(Person,"age",{
    configurable: false,
    enumerable: false,
    writable: false,
    value: 28,
})
console.log(Person.age);//28
console.log(delete(Person.age));//不可删 false
console.log(Person.age=20);
Prson.age = 20;
console.log(Person.age)//28,只读
定义多个属性  definePropertys(object,{
age:{
        value:23
    },
name{
        configurable:false
    }
});
2)访问器属性:不包含数据,在读取时调用geter函数,写入时调用seter函数,该属性必须用defineProperty方法定义
如:
Object.defineProperty(Person,'name',{
    get:function(){
        return this.name;    
    },
    set:function(){

        console.log("修改");
    }
});
Person.name = "Li";//修改
读取特性:Object.getOwnPropertyDescriptor(object,"property")(..还好不常用);
重点来了:
1)创建对象
工厂模式:
function Person(name,age){
    var o = new Object();
    o.name = name;
    o.age = age;

    o.sayName = function(){
        console.log(this.name);
    }
    return o;
}
var p1 =new Person("许涛",32);
构造函数模式:
var Person = function(name,age){
    this.name = name;
    this.age = age;

    this.sayName = function(){
        console.log(this.name);
    }
}
var p1 = new Person(name,age);
原型模式:
var Person = function(){};
Person.prototype.name = "马云";
Person.prototype.age = 11;
Person.prototype.sayName = function(){
    console.log(this.name); 
}
简写:
Person.prototype = {
    name:"马云",
    age:12,
    sayName: function(){
        console.log(this.name);
    }
}
var p1 = new Person();
原型模式缺点,每个对象实例属性一样
例如:
Person.prototype.friends =["许涛","马云","张三"];
var p2 = new Person();
P2.friends.push("John");
console.log(p1.friends);//["许涛","马云","张三","John"]
构造函数模式缺点:对象方法创建太多了影响性能,因为每个对象创建时都new
了一个方法

所以组合使用构造函数模式与原型模式可以有效避免缺点,集二者之长(使用最多):
function Person(name,age){
    this.name = name;
    this.age = age;
    this.friends = ["JOhn","Li"];

}
Person.prototype = {
    sayName: function(){
        console.log("this.name");
    }
}
var p1 =new Person("peter",32);
var p2 = new Person("安琪",18);
p2.friends.push("peter");
console.log(p1.friends);
console.log(p2.friends);
还有其他自定义模式都是基于前三种模式进化出来的。。
2)继承
//原型链继承:
function Person(){
    this.type = "man";
}
Person.prototype.sayType = function(){
    console.log("my name is: "+this.type)
}
//子对象
function Student(){
    this.job = "student";
}
//继承
Student.prototype =new Person();
var xiaoming = new Student();
console.log(xiaoming.type);
缺点:属性共享问题
Person.prototype.hairs =["black","green","yellow"];
var stu1 = new Student();
var stu2 = new Student();
stu2.hairs.push("blue");
console.log(stu1.hairs,stu2.hairs);
//构造函数继承:
//子对象
function Chinese(){
    //继承
    Person.call(this);
    this.country = "China";

}
var c1 = new Chinese();
console.log(c1.type);//true
//组合继承:(常用)
function People(name){
    this.name = name;

}
People.prototype.sayName = function(){
    console.log(this.name);
    return this.name;
}
//子对象
function Man(){
    People.call(this);
}
Man.prototype = new People();
Man.prototype.constructor = Man;
var man1 = new Man();
console.log(man1.name);
console.log(man1.sayName);
//缺点:无论何时都要调用两次父类
//原型式继承
function object(o){
    function F(){};
    F.prototype = o;
    return new F();
}//es5 新增Object.create()方法与object()方法一样
//寄生式继承
function clone(o){
    var clone = object(o);
    //添加新方法
    clone.sayHi = fuction(){
        alert("Hi");
    }
    return clone; 
}
//寄生组合式继承
function iher(subType,superType){
    var prototype = object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
//实例
function SuperType(name){
    this.name = name;   
}
SuperType.prototype.sayName = function(){
    console.log(this.name); 
}
//子对象
function SubType(name,age){
    SuperType.call(this,name);
    this.age = age;
}
//不用两次调用父类了
iher(SubType,SuperType);

猜你喜欢

转载自blog.csdn.net/qq_24308659/article/details/80950617