您的位置:首页 > Web前端 > JavaScript

JavaScript面向对象原理

2016-01-31 20:13 513 查看
JavaScript面向对象原理
sf2gis@163.com
2016年1月28日
 

1  目标:实现封装、继承、多态等面向对象的基本功能。

2 原理:使用prototype、function 、new、this模拟面向对象的类

JavaScript是面向对象语言,但不使用类(根本不存在类)。JavaScript的面向对象是基于prototype和function的,而不是基于类的。

参考:http://www.w3school.com.cn/js/js_objects.asp

http://www.2cto.com/kf/201409/339520.html

2.1 封装:将属性和方法封闭在内部。这里使用function作为基础封装。

function声明一个特殊对象,可以识别()直接运行(常规函数),也可以识别new创建一个对象(具有类的功能,构造函数)。

JavaScript内部有两上基本的function:Object和Function。

使用new Object()将生成一个新的对象实例,而使用new Function()将生成一个新的function对象。

权限控制:使用闭包(closure)模拟public,private(没有protected等)。一般情况下闭包的作用是指定访问权限,因此只需要将闭包设定为匿名函数,返回内部function对象。

2.1.1闭包:意指封闭的作用域,在此作用域中可以操作,外部无法操作。因此可以在此作用域中定义private变量,外部无法操作(与java的类相反,java在内部定义private变量)。

参考:http://www.cnblogs.com/starweb/archive/2013/02/17/2914023.html

闭包使用的外部作用域中变量由于被闭包对象使用,将不能被回收。

一般使用嵌套定义的函数来定义闭包对象。外部函数封装一个封闭的作用域(实际上如果不使用匿名函数,也可以开放一些接口),返回内部对象。

//closure

var M=(function(){

      var a=2;//private

      var b=3;//private

      var sum={};

      sum.add=function(){//public

           return a+b;

      };

      return sum;

})();

2.1.1.1  示例:private 与public

//test.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

 

<html>

<head>

      <title>Untitled</title>

</head>

 

<body>

 

Hello World!

<scripttype="text/javascript">

window.onload =function(){

  console.log("loaded.");

  var cls=new Cls();

  console.log("new Cls()=");

  console.log(cls);

  var s=cls.sum;

  console.log("cls.sum=");

  console.log(s);

  console.log("s.add()="+s.add());

};

 

 

//closure

function Cls(){

      var a=2;//private

      var b=3;//private

      var sum={};

      sum.add=function(){//public

           return a+b;

      };

      this.sum = sum;

}

</script>

</body>

</html>

 

2.1.1.2 示例:带有私有数据的类

//test.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

 

<html>

<head>

      <title>Untitled</title>

</head>

 

<body>

 

Hello World!

<scripttype="text/javascript">

window.onload =function(){

  console.log("loaded.");

  var s=M;

  console.log("sum=");

  console.log(s);

  console.log("s.add()="+s.add());

};

 

 

//closure

var M=(function(){

      var a=2;//private

      var b=3;//private

      var sum={};

      sum.add=function(){//public

           return a+b;

      };

      return sum;

})();

</script>

</body>

</html>

2.1.2插件:一般指具有私有数据、方法等比较完备的闭包对象,作用类似C/S的插件。

参考:http://zhidao.baidu.com/question/357810911.html

如jQuery就是一个插件。

示例:示例:带有私有数据的类

2.2 继承:使用原型(prototype)链直接复制模拟。

在使用的function对象封装对象时,为了增加继承功能(也就是能够利用父类的属性和方法),增加了prototype属性(对应的Object对象增加了__proto__属性)。这个属性指向一个function的实例(需要new出来的),在new此function时,就会先将此实例copy一份到此function的实例,从而实现了复用基类的模拟。

Object是所有new出来的对象的根原型(prototype)(用__proto__属性表示其继承层次的原型链,用constructor表示其直接function对象),而Function是所有function对象的原型(prototype)(用prototype属性定义)。因为JavaScript中所有的变量都是对象,所以function对象具有prototype和__proto__两个属性。

Object和Function本身定义了一些通用方法。

参考:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html

http://www.nowamagic.net/librarys/veda/detail/587

http://blog.sina.com.cn/s/blog_5f044a740100eqef.html

2.3 多态:是在继承的基础上,处理基类和子类同名方法或属性。

在继承的基础上,增加多态就是要用子类的属性和方法重写基类的属性和方法(一般只重写方法)。JavaScript在处理多态时会将子类中属性和方法覆盖原型中的属性和方法来实现多态。

为了处理当前new出的function的对象,增加了this来指代。

new关键字的规则是:new的function不应该有返回值(作为构造函数不应该有返回值,默认应该返回this)。如果function带有返回值(有return)则如果是基本类型就忽略,如果是对象替代this返回。

参考:http://www.jb51.net/article/54154.htm

2.4 示例:Object和Function

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

 

<html>

<head>

      <title>Untitled</title>

</head>

 

<body>

 

Hello World!

<scripttype="text/javascript">

window.onload =function(){

  console.log("loaded.");

  console.log("Object=");

  console.log(Object);

  console.log("Object.prototype=");

  console.log(Object.prototype);

  console.log("Object.__proto__=");

  console.log(Object.__proto__);

  console.log("Function=");

  console.log(Function);

  console.log("Function.prototype=");

  console.log(Function.prototype);

  console.log("Function.__proto__=");

  console.log(Function.__proto__);

};

</script>

</body>

</html>

3 流程:定义基类function,定义子类function,子类中重写基类的方法,指定子类的基类prototype。

3.1 定义基类function

//Base

function Base(){

      this.log=function(){

           console.log("Base.log");

      };

      this.debug=function(){

           console.debug("Base.debug");

      };

}

3.2 定义子类function,并在子类中重写基类的方法

//Sub1

function Sub1(){

      this.log=function(){

           console.log("Sub1.log");

      };

}

3.3 指定子类的基类prototype。

Sub1.prototype=new Base();//function use prototype

注意:也可以使用子类的this象的__proto__属性指定,但这不符合面向对象的思想,不推荐。

3.4 示例

//test.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

 

<html>

<head>

      <title>Untitled</title>

</head>

 

<body>

 

Hello World!

<scripttype="text/javascript">

window.onload =function(){

  console.log("loaded.");

  var o=new Object();

  console.log(o);

  var base=new Base();

  base.log();

  base.debug();

  console.log(base);

  var sub1=new Sub1();

  sub1.log();

  sub1.debug();

  console.log(sub1);

  var sub2=new Sub2();

  sub2.log();

  sub2.debug();

  console.log(sub2);

  console.log(sub2.__proto__);

  console.log(sub2.prototype);//Ojectinstance,not Function instance

};

//Base

function Base(){

      this.log=function(){

           console.log("Base.log");

      };

      this.debug=function(){

           console.debug("Base.debug");

      };

}

 

//Sub1

function Sub1(){

      this.log=function(){

           console.log("Sub1.log");

      };

}

Sub1.prototype=new Base();//function use prototype

 

//Sub2

function Sub2(){

      this.__proto__=new Base();//object use __proto__

      this.log=function(){

           console.log("Sub2.log");

      };

}

</script>

</body>

</html>

4 方法

 

5 示例

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息