面向对象常用概念
一讲到面向对象,马上就会想到封装、继承、多态3个主要特性。不过JavaScript不是面向对象语言,只是基于对象的语言。
JS中的封装和继承跟C++,Java差异比较大,里面没有子类和父类的概念,也没有类和实例的区分,只是通过prototype来模拟实现类似的效果。
封装: 简单的理解就是有把属性(变量)、方法(函数)放到一个类中。并且通过限定属性、方法为私有或公共来隐藏内部实现和对外提供接口。
JS的类
在Java中,我们使用一个类一般是这样
class TC{
public TC() { }
}
TC tc = new TC();
但是在JS中没有类的概念,咋整呢?
JS中用了个奇怪的办法,就是用构造函数来实例化类。
要弄明白这玩艺得先了解两个概念。
(1)函数也是基本数据类型。
JS中借鉴了函数式编程的思想,函数也跟数值、字符等一样是个基本类型,这点跟java、c++很不一样。
(2) 借鉴面向对象语言思想并做简化
像java、C++的类中都会至少有一个构造函数(一个也没有话,编译器也会自动生成一个)。 于是JS借鉴的时候就把类给去掉,只留下构造函数。
因为js中函数本身也是一种数据类型,你也就可以把构造函数理解成类也行。
js类的简单示例
function TC(para){
this.info = para;
}
var tc = new TC('arwen‘);
document.write(tc.info);
JS类的封装
我们知道类中有属性和方法,并且可以指定哪些是私有的,只有类本身能访问,共有的类实例化对象也能访问。
function TC(para){
var private_info = 'this is private'; //私有属性
var private_fun = function(){ //私有方法
document.write('write something by private function');
}
this.public_info = para; //公有属性
this.public_fun = function() { //公有方法
document.write('write something by public function');
private_fun(); //内部调用私有方法,ok
}
}
var tc = new TC("arwen"); //实例化一个类对象
document.write(tc.public_info); //调用公有属性,ok
tc.public_fun(); //调用公有方法,ok
//document.write(tc.private_info); //调用私有属性,出错
//tc.private_fun(); //调用私有方法,出错
公有属性和方法可以通过类的实例对象去调用,而私有属性和方法只能类的内部调用。
var的用法
很多时候变量前面加不加var貌似都一样,js本来也是弱类型语言。不过有几种场景,用不用var还是有区别的
(1)只声明变量
假如只声明一个变量,但不赋值,则必须用var。例如
var info;
(2)函数体内局部变量
在一个函数体内function fun(){
var one = "this is local var"; //使用了var表明是局部变量,在函数外面不能使用
two = "this is global var"; //这是全局变量,在函数体外面也能使用
}
静态变量、函数
在C++,Java中如果某个属性或方法是属于类本身,跟实例对象无关,就可以弄成静态属性或静态方法.并通过关键字static来标志。
静态变量和函数除了逻辑上使设计思路清晰点,还有个好处就是可以节省内存空间。类的普通属性和方法在类实例化一个对象时都会分配内存,而静态变量、函数不管有多少对象都只分配一次内存。
function TC(){
}
TC.info_one = "number one";
TC.prototype.info_two = "number two";
TC.fun_one = function(){
};
TC.prototype.fun_two=function{
}
上面的两个变量其实都是静态变量,只不过有点区别,info_one只能通过类名直接引用,不能通过对象名引用,只通这样调用TC.info_one;
info_two只能通过对象名引用,不能通过类名引用。只能这样: var tc = new TC(); document.write(tc.info_two);
静态方法fun_one只能通过类名引用,TC.fun_one(); fun_two只能通过对象名引用: var tc = new TC(); tc.fun_two();