JS类的定义和继承

JS中的对象是以json格式存储的,有以下几种方式创建对象:

1.构建散列表

直接将对象的属性和方法构造成散列表

var Tom = {
    name : 'tom',
    age : 18,
    showName : function(){
        alert('我的名字叫'+this.name);    
    },
    showAge : function(){
        alert('我今年'+this.age+'岁');    
    }
}

这样创建了一个含有name和age属性,showName和showAge方法的对象

这种方法创建对象的缺点: 只有类而没有对象的概念.会创建多个相似对象

2.工厂模式

通过工厂模式,我们可以抽象出类的结构.

function createPerson(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.showname = function(){
        alert('我的名字叫'+this.name);    
    };
    o.showage = function(){
        alert('我今年'+this.age+'岁');    
    };
    o.showjob = function(){
        alert('我的工作是'+this.job);    
    };
    return o;
}

var tom = createPerson('tom',18,'程序员');
tom.showname();

alert(tom.constructor)	// 返回ƒ Object() { [native code] }

函数 createPerson()根据接受的参数来构建一个包含所有必要信息的Person对象.

优点: 抽象出了类的结构,解决了创建多个相似对象的问题

缺点: 无法解决识别问题,系统无法判断tom对象是哪个类的实例

3.构造函数

为Person类创建构造函数

function Person(name,age,job){            
    this.name = name;
    this.age = age;
    this.job = job;
    this.showname = function(){
        alert('我的名字叫'+this.name);    
    };
    this.showage = function(){
        alert('我今年'+this.age+'岁');    
    };
    this.showjob = function(){
        alert('我的工作是'+this.job);    
    };
}
var tom = new Person('tom',18,'程序员');
var jack = new Person('jack',19,'销售');
alert(tom.showjob==jack.showjob);	// 返回false

该方法的特点:

  1. 没有显示创建对象
  2. 没有return语句
  3. 直接将属性赋值给this对象(this对象总是指向当前作用域) 
  4. 用new语句构造一个新对象,若不使用new,则this对象指向Global对象(在浏览器中指向window对象)
    Person("George", 27, "司机"); // 添加到 window 
    window.sayName();      // 弹出"George" 

优点: 可以通过constructor属性或者instanceof操作符来获取对象所在的类:

alert(tom.constructor == Person);  //true 
alert(jack.constructor == Person); //true

alert(tom instanceof Object);  //true 
alert(jack instanceof Person); //true 
alert(tom instanceof Object);  //true 
alert(jack instanceof Person); //true

 可以看到,tom和jack的构造函数是Person(),是Person类的实例.

缺点: 实例之间没有共享类的方法

4.原型模式

每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法. 不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中.

function Person(name,age,job){        
    this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.showname = function(){
    alert('我的名字叫'+this.name);    
};
Person.prototype.showage = function(){
    alert('我今年'+this.age+'岁');    
};
Person.prototype.showjob = function(){
    alert('我的工作是'+this.job);    
};
var tom = new Person('tom',18,'程序员');
var jack = new Person('jack',19,'销售');

alert(tom.showjob==jack.showjob);	// 返回true

alert(tom instanceof fclass);	// 返回true
alert(tom instanceof sclass);	// 返回true
tom.constructor == fclass;		// 返回true
tom.constructor == sclass;		// 返回false

可以看到实例之间共享类的函数,也可以通过instanceof操作符来获取对象所在的类,是一个比较完美的创建类的方法.(严格来讲,constructor属性返回的是对象的构造函数,因此通过instanceof判断对象所在的类较靠谱)

类的继承

在子类中通过call()方法调用父类的构造函数,将子类的prototype属性继承自父类并加以修改

function fclass(name,age){
    this.name = name;
    this.age = age;
}
fclass.prototype.showname = function(){
    alert(this.name);
}
fclass.prototype.showage = function(){
    alert(this.age);
}

function sclass(name,age,job){
    fclass.call(this,name,age);
    // 在this(sclass)作用域中调用fclass
    this.job = job;
}
sclass.prototype = new fclass(); // 继承函数原型
sclass.prototype.showjob = function(){
    alert(this.job);
}
var tom = new sclass('tom',19,'全栈工程师');
tom.showname();
tom.showage();
tom.showjob();

在ES6中引入了class关键字,可以更方便的创建类.

猜你喜欢

转载自blog.csdn.net/ncepu_Chen/article/details/82901736