JavaScript之面向对象与原型

时间:2022-05-22 19:47:55

What is JavaScript

where

    传统的网页客户端向服务器提交信息是采用表单验证,但是表单验证交互性极差,为用户带来的体验也不好。于是,JavaScript出现!

what

    JavaScript是一门客户端脚本语言,它不像.net需要sdk,Java需要sdk,它是一种解释型或者说是直译型的脚本语言,不用编译,运行过程中朱行进行解释!

why

    JavaScript主要应用于为网页添加各式各样的动态功能,为用户提供更加流程美观的浏览效果。

how

    JavaScript可以直接嵌入HTML中,也可以写成单独的js文件实现,这样同样方便结构和行为的分离。JavaScript也同其他语言一样,有自己的基本数据类型、表达式和算数运算符及程序的基本程序框架。


JavaScript的面向对象和原型

    之前我们学习c#、设计模式等知识的知识少不了学习面向对象,但是之前的面向对象的语言都有一个标志,那就是类,通过类创建任意个具有相同属性和方法的对象。但是JavaScript可没有类这个概念,那他到底是怎么创建对象的呢?他的面向对象如何体现的呢?

创建对象

1.工厂模式:简单的函数创建对象,为对象添加属性和方法,然后返回对象。如下代码:

function createObject(name,age){    // 集中创建函数体;
var obj = new Object;         // 函数体内创建Object;
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name+this.age+"运行中...";
};
return obj;
}
优点:解决大量实例化重复的问题。 
缺点:对象和实例的识别无法搞清楚。


2.构造函数:自定义引用类型,像创建内置对象实例一样使用new操作符。如下代码:

function Box(name,age){          // 构造函数模式;
this.name = name;           // this代表对象Box;
this.age = age;
this.run = function(){
return this.name+this.age+"运行中...";
};
}
优点:解决了重复实例化以及对象识别的问题。


3.原型

  使用函数的prototype属性来指定可以共享的属性和方法,可以让所有对象实例共享它所包含的属性和方法,不用在构造函数中定义对象的属性和方法,而是可以直接将这些信息添加到原型中。

  但是原型最大的优点共享同样也是他最大的缺点,于是将构造函数模式(对象不共享的数据)和原型模式(对象共享的数据)组合使用。代码如下:

 function Box(name,age){             // 不共享的使用构造函数;
this.name = name;
this.age = age;
this.family = ['father','moter'];
};
Box.prototype = { // 共享的使用原型模式;
constructor:Box,
run:function(){
return this.name+this.age+this.family;
}
}

这样做既解决了原型模式传参的问题,也解决了共享的问题!


继承

  面向对象一个很基础的概念,继承,子类继承父类或者实现接口。但是JavaScript只支持继承,并且主要依靠原型链完成。原型链主要是通过将一个类型的实例赋值给另一个构造函数的原型完成的。

 function Box(){                 // Box构造;
this.name = 'Lee';
}
function Desk(){ // Desk构造;
this.age = 100;
}
Desk.prototype = new Box(); // 通过创建Box实例,并赋值给Desk.prototype实现的;通过原型,形成链条;
// 实质是:重写了Desk的原型对象,取而代之的是一个新类型Box的实例;
// 也就是说原来存在于Box实例中的属性和方法,现在也存在与Desk.prototype中了;
var desk = new Desk();
console.log(desk.age); // 100;
console.log(desk.name); // =>Lee;

function Table(){
this.level = 'AAA';
}
Table.prototype = new Desk(); // 继续原型链继承;Table继承了Desk;
var table = new Table();
console.log(table.name); // Lee;
JavaScript之面向对象与原型
最好的继承方法:寄生组合式继承

// 超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部;
function Box(name){
this.name = name;
this.arr = ['brother','sister'];
}
Box.prototype.run = function(){
return this.name;
}
function Desk(name,age){
Box.call(this,name); // 第二次调用Box;
this.age = age;
}
Desk.prototype = new Box(); // 第一次调用Box;

// 寄生组合式继承:
// 通过借用构造函数来继承属性,
// 通过原型链的混成形式来继承方法;
// 解决了两次调用的问题;
function obj(o){
function F(){};
F.prototype = o;
return new F();
}
function create(box,desk){
var f = obj(box.prototype);
f.constructor = desk;
desk.prototype = f;
}
function Box(name){
this.name = name;
this.arr = ['brother','sister'];
}
Box.prototype.run = function(){
return this.name;
}
function Desk(name,age){
Box.call(this,name);
this.age = age;
}
inheritPrototype(Box,Desk); // 通过这里实现继承;

var desk = new Desk('Lee',100);
desk.arr.push('father');
console.log(desk.arr);
console.log(desk.run());

var desk2 = new Desk('Jack',200);
console.log(desk2.arr); // 两次引用问题解决;