发布网友 发布时间:2024-09-16 19:12
共1个回答
热心网友 时间:2024-09-20 20:41
javascript里面有类吗?javascript有类的概念。
js里面类通过function进行定义,有些类似c++的struct定义。
代码示例:
function?MyClass(){
???this.a?=?'2';
???this.show=function(){
??????alert('1');
???}
}
var?myClass?=?new?MyClass();
alert(myClass.a);//获取属性
myClass.show();//调用类方法
如何理解Javascript中类和对象这两个概念
在说这个话题之前,我想先说几句题外话:最近偶然碰到有朋友问我“hoisting”的问题。即在js里所有变量的声明都是置顶的,而赋值则是在之后发生的。可以看看这个例子:
vara='global';
(function(){
alert(a);
vara='local';
})();
大家第一眼看到这个例子觉得输出结果是什么?‘global’?还是‘local’?其实都不是,输出的是undefined,不用迷惑,我的题外话就是为了讲这个东西的。
其实很简单,看一看JavaScript运行机制就会明白。我们可以把这种现象看做“预声明”。但是如果稍微深究一下,会明白得更透彻。
这里其实涉及到对象属性绑定机制。因为所有JavaScript函数都是一个对象。在函数里声明的变量可以看做这个对象的“类似属性”。对象属性的绑定在语言里是有分“早绑定”和“晚绑定”之分的。
【早绑定】
是指在实例化对象之前定义其属性和方法。解析程序时可以提前转换为机器代码。通常的强类型语言如C++,java等,都是早绑定机制的。而JavaScript不是强类型语言。它使用的是“晚绑定”机制。
【晚绑定】
是指在程序运行前,无需检查对象类型,只要检查对象是否支持特性和方法即可。可以在绑定前对对象执行大量操作而不受任何惩罚。
上面代码出现的“预声明”现象,我们大可用“晚绑定”机制来解释。在函数的作用域中,所有变量都是“晚绑定”的。即声明是顶级的。所以上面的代码和下面的一致:
vara='global';
(function(){
vara;
alert(a);
a='local';
})();
在alert(a)之前只对a作了声明而没有赋值。所以结果可想而知。
!--题外话到此结束--
RT:本文要说的是,在JavaScript里,我所知道的几种定义类和对象的方式:!--声明:以下内容大部分来自《JavaScript高级程序设计》,只是个人叙述方式不同而已--
【直接量方式】
使用直接量构建对象是最基础的方式,但也有很多弊端。
varObj=newObject;
Obj.name='sun';
Obj.showName=function(){
alert('this.name');
}
我们构建了一个对象Obj,它有一个属性name,一个方法showName。但是如果我们要再构建一个类似的对象呢?难道还要再重复一遍?
NO!,我们可以用一个返回特定类型对象的工厂函数来实现。就像工厂一样,流水线的输出我们要的特定类型结果。
【工厂方式】
functioncreateObj(name){
vartempObj=newObject;
tempObj.name=name;
tempObj.showName=function(){
alert(this.name);
};
returntempObj;
}
varobj1=createObj('obj_one');
varobj2=createObj('obj_two');
这种工厂函数很多人是不把他当做构建对象的一种形式的。一部分原因是语义:即它并不像使用了运算符new来构建的那么正规。还有一个更大的原因,是因为这个工厂每次产出一个对象都会创建一个新函数showName(),即每个对象拥有不同的版本,但实际上他们共享的是同一个函数。
有些人把showName在工厂函数外定义,然后通过属性指向该方法,可以避开这个问题:
代码
可惜的是,这种方式让showName()这个函数看起来不像对象的一个方法。
【构造函数方式】
这种方式是为了解决上面工厂函数的第一个问题,即没有new运算符的问题。可是第二个问题它依然不能解决。我们来看看。
functionObj(name){
this.name=name;
this.showName=function(){
alert(this.name);
}
}
varobj1=newObj('obj_one');
varobj2=newObj('obj_two');
它的好处是不用在构造函数内新建一个对象了,因为new运算符执行的时候会自动创建一个对象,并且只有通过this才能访问这个对象。所以我们可以直接通过this来对这个对象进行赋值。而且不用再return,因为this指向默认为构造函数的返回值。
同时,用了new关键字来创建我们想要的对象是不是感觉更“正式”了。
可惜,它仍然不能解决会重复生成方法函数的问题,这个情况和工厂函数一样。
【原型方式】
这种方式对比以上方式,有个很大的优势,就是它解决了方法函数会被生成多次的问题。它利用了对象的prototype属性。我们依赖原型可以重写对象实例。
varObj=function(){}
Obj.prototype.name='me';
Obj.prototype.showName=function(){
alert(this.name);
}
varobj1=newObj();
varobj2=newObj();
我们依赖原型对构造函数进行重写,无论是属性还是方法都是通过原型引用的方式给新建的对象,因此都只会被创建一次。可惜的是,这种方式存在两个致命的问题:
1。没办法在构建对象的时候就写入想要的属性,因为原型在构造函数作用域外边,没办法通过传递参数的方式在对象创建的时候就写入属性值。只能在对象创建完毕后对值进行重写。
2。致命问题在于当属性指向对象时,这个对象会被多个实例所共享。考虑下面的代码:
varObj=function(){}
Obj.prototype.name='me';
Obj.prototype.flag=newArray('A','B');
Obj.prototype.showName=function(){
alert(this.name);
}
varobj1=newObj();
varobj2=newObj();
obj1.flag.push('C');
alert(obj1.flag);//A,B,C
alert(obj2.flag);//A,B,C
是的,当flag属性指向对象时,那么实例obj1和obj2都共享它,哪怕我们仅仅改变了obj1的flag属性,但是它的改变在实例obj2中任然可见。
面对这个问题,让我们不得不想是否应该把【构造函数方式】和【原型方式】结合起来,让他们互补。。。
【构造函数和原型混合方式】
我们让属性用构造函数方式创建,方法用原型方式创建即可:
varObj=function(name){
this.name=name;
this.flag=newArray('A','B');
}
Obj.prototype={
showName:function(){
alert(this.name);
}
}
varobj1=newObj();
varobj2=newObj();
obj1.flag.push('C');
alert(obj1.flag);//A,B,C
alert(obj2.flag);//A,B
这种方式有效地结合了原型和构造函数的优势,是目前用的最多,也是副作用最少的方式。
不过,有些追求完美的家伙还不满足,因为在视觉上还没达到他们的要求,因为通过原型来创建方法的过程在视觉上还是会让人觉得它不太像实例的方法(尤其对于传统OOP语言的开发者来说。)
所以,我们可以让原型活动起来,让他也加入到构造函数里面去,好让这个构造函数在视觉上更为统一。而这一系列的过程只需用一个判断即可完成。
varObj=function(name){
this.name=name;
this.flag=newArray('A','B');
if(typeofObj._init=='undefined'){
Obj.prototype={
showName:function(){
alert(this.name);
}
};
Obj._init=true;
}
}
如上,用_init作为一个标志来判断是否已经给原型创建了方法。如果是那么就不再执行。这样其实在本质上是没有任何变化的,方法仍是通过原型创建,唯一的区别在于这个构造函数看起来“江山统一”了。
但是这种动态原型的方式是有问题的,《JavaScript高级程序设计》里并没有深究。创建第一个对象的时候会因为prototype在对象实例化之前没来的及建起来,是根本无法访问的。所以第一个对象是无法访问原型方法的。同时这种方式在子类继承中也会有问题。
关于解决方案,我会在下一文中说明。
其实就使用方便来说的话,个人觉得是没必要做这个判断的。。。呵呵^_^
JavaScript里面的类是什么意思?JavaScript是面向对象的语言,引用数据类型都是对象,包括函数也是对象,同时还可以通过Object对象自定义对象。
但是,和其他面向对象语言(如Java等高级语言)比,也有很大差异,JS中没有类或接口的概念,即不能直接定义抽象的类,也不能直接实现继承。不过,为了编程的方便,我们可以在JS中模拟类和继承的行为。
创建对象实例或类(虽然没有类的概念,但是可以把用于创建新对象的对象看作类),可以通过构造函数来实现,构造函数就是具有一系列属性和行为作为函数体的函数,可以通过函数参数传入值。它就相当于Java中类的构造函数,需要时可以通过varinstanceObj=newConstructorFunc(para1,para2,...)来创建对象(实例)。
JS的对象中还有一个重要概念,即原型。每个对象都有原型,原型也是一个对象,可以看做是构造函数的映像,是创建实例的模型。对象(类)的属性prototype即是对原型对象的引用,创建实例后,也有属性__proto__指向原型对象,但该属性是隐含的。
由于不断创造新对象(实例),一级一级的传递原型对象,即可构成原型链。通过原型链,即可实现继承。首先将父类对象的实例给子类的原型ChildCons.prototype=newParentCons(),再在子类构造函数中调用父类构造函数将继承的属性初始化。继承的变通方法还有很多,可以参考一些资料。
JavaScript里面的子类和父类是什么意思?js是通过prototype实现的继承,
如ClassA.prototype=newClassB().
就可以说ClassA是ClassB的子类,同时ClassB是ClassA的父类
js中定义一个class其实就是一个function,如
varClassA=function(){
}
====怎么最近好像老有人问这个?
javascript为什么没有类原因比较多,我个人分析认为主要有以下两大方面的原因
历史遗留原因
javascript在当时设计之初,是带着商业竞争目的的,js前身为livescript,主要是使得浏览器初步具备客户端能力,因此并不是特别完善。
网页端js开发在相当一段时间内,由于浏览器的js解释引擎性能并不高,而且网络带宽也比较小,因此绝大多数站点的代码规模并不大,主要针对页面内容一些简单交互逻辑,在此前提下,浏览器厂商以及工业界都没有强大的动力去实现面向对象版本的js。
技术实现原因
考虑到到网页环境的特殊性,使用原型继承而不是类继承的方式,更节约内存空间,而且解释器的实现更为简单。
js开源界在不断的技术积累中,开发者已经逐渐适应了没有类的js开发模式,在js中实现真正的类反而显得有些鸡肋。
最后:虽然现在ES6标准中已经有class关键字了,但是归根到底类还是一个语法糖,其底层还是基于原型继承的。
JavaScript里面的类是什么意思????js里面的类就是一个函数
跟java、C#、C\C++定义类有很大的区别
具体的定义一个类可以用下面这种方式
function?student(){
}
上面这个方法定义了一个类(当然你也可以说他是定义了一个方法)
可以这样实例化这个类的对象
var?stu?=?new?student();
当然了,这个类他没有属性也没有自己的方法
下面再定义一个类,他有自己的一个方法
function?student1(){
????this.getAge?=?function(){
????????return?18;
????}
}
此时如果实例化一个student1类的对象,该对象会有一个getAge的方法。
接着定义一个类,有自己的初始化操作(相当于类构造函数里面的代码)
function?student2(){
????var?age?=?0;
????age?=?18;????????//这句代码和上面那句代码会在实例化该类对象时执行。
????this.getAge?=?function(){
????????return?age;
????}
}
当然了,js也可以继承,但是在这里就不一一列举了。