继承(由另一个类(或多个类)得来类的属性和方法的能力)
多态(一个对象在不同情况下的多种形态)
定义类或对象
第一种:基于Object对象
var person = new Object(); person.name = "Rose"; person.age = 18; person.getName = function () { return this.name; }; console.log(person.name);//Rose console.log(person.getName);//function () {return this.name;} console.log(person.getName());//Rose
缺点:不能创建多个对象。
第二种:基于字面量方式
var person = { name : "Rose", age : 18 , getName : function () { return this.name; } }; console.log(person.name);//Rose console.log(person.getName);//function () {return this.name;} console.log(person.getName());//Rose
优点:比较清楚的查找对象包含的属性和方法;
缺点:不能创建多个对象。
第三种:工厂模式
方式一:
function createPerson(name,age) { var object = new Object(); object.name = name; object.age = age; object.getName = function () { return this.name; }; return object; } var person1 = createPerson("Rose",18); var person2 = createPerson("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//false//重复生成函数,为每个对象都创建独立的函数版本
优点:可以创建多个对象;
缺点:重复生成函数getName(),为每个对象都创建独立的函数版本。
方式二:
function createPerson(name,age) { var object = new Object(); object.name = name; object.age = age; object.getName = getName; return object; } function getName() { return this.name; } var person1 = createPerson("Rose",18); var person2 = createPerson("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享同一个函数
优点:可以创建多个对象;
缺点:从语义上讲,函数getName()不太像是Person对象的方法,辨识度不高。
第四种:构造函数方式
方式一:
function Person(name,age) { this.name = name; this.age = age; this.getName = function () { return this.name; } } var person1 = new Person("Rose",18); var person2 = new Person("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName); //false//重复生成函数,为每个对象都创建独立的函数版本
优点:可以创建多个对象;
缺点:重复生成函数getName(),为每个对象都创建独立的函数版本。
方式二:
function Person(name,age) { this.name = name; this.age = age; this.getName = getName ; } function getName() { return this.name; } var person1 = new Person("Rose",18); var person2 = new Person("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName); //true//共享同一个函数
优点:可以创建多个对象;
缺点:从语义上讲,函数getName()不太像是Person对象的方法,辨识度不高。
第五种:原型方式
function Person() { } Person.prototype.name = 'Rose'; Person.prototype.age = 18; Person.prototype.getName = function () { return this.name; }; var person1 = new Person(); var person2 = new Person(); console.log(person1.name);//Rose console.log(person2.name);//Rose//共享同一个属性 console.log(person1.getName === person2.getName);//true//共享同一个函数
缺点:它省略了为构造函数传递初始化参数,这在一定程序带来不便;另外,最主要是当对象的属性是引用类型时,它的值是不变的,总是引用同一个外部对象,所有实例对该对象的操作都会影响其它实例:
function Person() { } Person.prototype.name = 'Rose'; Person.prototype.age = 18; Person.prototype.lessons = ["语文","数学"]; Person.prototype.getName = function () { return this.name; }; var person1 = new Person(); person1.lessons.push("英语"); var person2 = new Person(); console.log(person1.lessons);//["语文", "数学", "英语"] console.log(person2.lessons);//["语文", "数学", "英语"]//person1修改影响了person2
第六种:构造函数+原型方式(推荐)
function Person(name,age) { this.name = name; this.age = age; } Person.prototype.getName = function () { return this.name; }; var person1 = new Person('Rose', 18); var person2 = new Person('Jack', 20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享原型中定义的方法
缺点:属性定义在构造函数内,方法定义在构造函数外,与面向对象的封装思想不符。
第七种:构造函数+动态原型方式(推荐)
方式一: