JavaScript面向对象原理
2016-01-31 20:13
513 查看
JavaScript面向对象原理
sf2gis@163.com
2016年1月28日
参考:http://www.w3school.com.cn/js/js_objects.asp
http://www.2cto.com/kf/201409/339520.html
JavaScript内部有两上基本的function:Object和Function。
使用new Object()将生成一个新的对象实例,而使用new Function()将生成一个新的function对象。
权限控制:使用闭包(closure)模拟public,private(没有protected等)。一般情况下闭包的作用是指定访问权限,因此只需要将闭包设定为匿名函数,返回内部function对象。
闭包使用的外部作用域中变量由于被闭包对象使用,将不能被回收。
一般使用嵌套定义的函数来定义闭包对象。外部函数封装一个封闭的作用域(实际上如果不使用匿名函数,也可以开放一些接口),返回内部对象。
//closure
var M=(function(){
var a=2;//private
var b=3;//private
var sum={};
sum.add=function(){//public
return a+b;
};
return sum;
})();
<!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>
<!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>
如jQuery就是一个插件。
示例:示例:带有私有数据的类
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
为了处理当前new出的function的对象,增加了this来指代。
new关键字的规则是:new的function不应该有返回值(作为构造函数不应该有返回值,默认应该返回this)。如果function带有返回值(有return)则如果是基本类型就忽略,如果是对象替代this返回。
参考:http://www.jb51.net/article/54154.htm
<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>
function Base(){
this.log=function(){
console.log("Base.log");
};
this.debug=function(){
console.debug("Base.debug");
};
}
function Sub1(){
this.log=function(){
console.log("Sub1.log");
};
}
注意:也可以使用子类的this象的__proto__属性指定,但这不符合面向对象的思想,不推荐。
<!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>
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
//Basefunction Base(){
this.log=function(){
console.log("Base.log");
};
this.debug=function(){
console.debug("Base.debug");
};
}
3.2 定义子类function,并在子类中重写基类的方法
//Sub1function 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 示例
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- 深入理解PHP之匿名函数
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 设计模式之创建型模式 - 特别的变量问题
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解