js 与 java 的各种坑爹
1.js string坑爹的“==”
js的String类型与java的String类型不同,比较的时候不用equals,可以直接用"==".
测试了下,这个"=="好像比较坑爹
<script type="text/javascript">
var a=new String("hehe");
var b=new String("hehe");
var c="hehe";
alert("a==c: "+(a==c));//true
alert("b==c: "+(b==c));//true
alert("a==b: "+(a==b));//false
alert("hehe"=="hehe");//true
</script>
怎么能有这么没道理的事情?a=c,b=c,但是a竟然不等于b!!!
我的结论是js中的String类型虽然没有equals方法,但是当String类型对象与另一个String类型的变量相比较的时候,使用的方法与java的equals方法相类似。而当两个String类型相比较的时候,"=="才与java中的"=="相类似,即比较两个对象是否是同一个对象。
与之相对应的java代码,则没有这种让人纠结的地方
String a=new String("hehe");
String b=new String("hehe");
String c="hehe";
String d="hehe";
System.out.println("a==b: "+(a==b));//false
System.out.println("a==c: "+(a==c));//false
System.out.println("c==b: "+(c==b));//false
System.out.println("c==d: "+(c==d));//true
System.out.println("a.equals(b): "+(a.equals(b)));//true
java中通过new创建的String对象用"=="相比较的时候,比较的是对象的地址值,而js中,只有当两个对象都是用new创建的时候,才比较地址值。
2.js中的数组与java中的List异同点:
相同点:
1.添加的元素类型可以不同。(java使用泛型后,只能添加规定的元素类型)
2.长度可变
不同点:
js中可以访问超过数组长度的角标,返回undefined,java中,list.get(index) index的值超过数组长度的话,运行时有异常: java.lang.IndexOutOfBoundsException
ArrayList list=new ArrayList();
list.add("re");
list.add(2);
System.out.println(list.get(2));//java.lang.IndexOutOfBoundsException
var t=[0,"a"];
document.write(t[5]);//undefined
3. js中的function
//js的函数可以看做一个类,它的属性分为:
//实例属性:使用this作为前缀
//类属性:使用函数名作为前缀
//局部变量:使用var声明或者直接赋值
/*与java不同的是,js的类属性只能通过类来访问,不能够用对象来访问
*在同一个类中,可以有同名的类属性和实例属性;
*/
var Person=function(name,age)
{
var me="memeda";
this.name=name;
this.age=age;
Person.gender="female";
this.gender="male";
Person.t="hehe";
}
var p=new Person("Lucy","32");
with(document)
{
write(p.name+"<br/>");//lucy
write(p.age+"<br/>");//32
write(p.gender+"<br/>");//male
write(Person.gender+"<br/>");//female
write(p.t+"<br/>");//undefined
write(p.me+"<br/>");//undefined
}
js对象的属性可以随意添加
上面的p对象并没有t、me属性,添加后:
p.me="ok";
p.t="ttok";
document.write(p.t+"<br/>");//ttok
document.write(p.me+"<br/>");//ok
4.js中函数是独立的,它不从属于任何类或者对象;
虽然js中的函数可以定义在某个类中,但它可以被其他类的对象调用;而java中的方法是实例方法或者是静态方法(类方法),是属于对象或者类的。call()方法作用:使得不同的对象能够调用某个方法。
//call的语法格式:函数名.call(调用对象,参数1,参数2···);没有参数的话可以省略
var wolf=function(name,voice,action){
this.name=name;
this.voice=voice;
this.action=action;
this.info=function(){
document.write(this.name+"的叫声是"+this.voice+"吃食物的方式是:"+this.action+"<br/>");
}
}
new wolf("wolf","ao~","撕咬").info();//wolf的叫声是ao~吃食物的方式是:撕咬
var cat=function(name,voice,action)
{
this.name=name;
this.voice=voice;
this.action=action;
}
new wolf("wolf","ao~","撕咬").info.call(new cat("猫","miao~","卖萌"));//猫的叫声是miao~吃食物的方式是:卖萌
5.js函数的参数传递与java方法的参数传递一样:都是值传递
var Person=function()
{
this.name="wang";
this.age="24";
}
var changeP=function(person)
{
person.age="1";
person.name="cheng";
person=null;
}
var p=new Person();
document.write("改变前,p.name="+p.name+",p.age="+p.age+"<br/>");// 改变前,p.name=wang,p.age=24
changeP(p);
document.write("改变后,p.name="+p.name+",p.age="+p.age+"<br/>");//改变后,p.name=cheng,p.age=1
document.write(p==null);//false
上面的例子中,changeP()中传入的参数是一个对象,调用这个方法的时候,实际传入的不是对象本身,而是一个对象地址值的副本。因为这个地址值与原来对象的地址值一样,所以能够修改对象的属性;而在p=null;这里,是切断了副本的引用,对原来的对象没有影响。在java中,得到的运算结果也是一样的。
class Person
{
String name;
String age;
public Person(String name,String age)
{
this.name=name;
this.age=age;
}
public String toString()
{
return "Person["+this.name+","+this.age+"]";
}
}
public class Test
{
public static void changeP(Person p)
{
p.age="0";
p.name="cheng";
p=null;
}
public static void main(String[] args) {
Person p=new Person("wang","24");
System.out.println("before "+p);//before Person[wang,24]
changeP(p);
System.out.println("after "+p);//after Person[cheng,0]
}
}
6.js有参数的函数在调用的时候,可以不传入参数;java有参数的方法必须传入参数;函数名是js中函数的唯一标识,js中没有java中重载的概念。
var method=function(t)
{
alert(t);
}
method();//undefined
如果在js代码中先后定义了两个同名的函数,即使函数传入的参数不同,后面的函数也会覆盖前面的。
var method1=function()
{
alert("没有参数的构造器");
}
var method1=function(t)
{
alert("有参数的构造器");
}
method1();//"有参数的构造器"
作为一种弱类型语言,js中需要参数的函数,一般都要先判断传入的参数是否符合要求
var changeName=function(p,newname)
{
if(typeof p==‘object‘&& typeof p.name==‘string‘ && typeof newname==‘string‘)
{p.name=newname;
document.write(p.name+"<br/>");}
else{
document.write("传入的参数类型不符合要求 "+typeof(p)+" "+typeof(newname)+"<br/>");
}
}
changeName();// 传入的参数类型不符合要求 undefined undefined
changeName("a","s");// 传入的参数类型不符合要求 string string
person={name:"wang"};
changeName(person,"zhang");// zhang
7.对象的属性
js中调用某个对象的属性可以用objName.propertyName的方式,调用类属性的方式是类名+属性名;
与java不同的是,js的属性可以为函数;在某些情况下,调用js属性必须使用objName[propertyName]的方式
var Person=function(name,age)
{
this.name=name;
this.age=age;
this.show=function(){
document.write("此人年龄: "+this.age+"此人姓名: "+this.name+"<br/>");
}
}
var p=new Person("wang","24");
for(var property in p)
{
// 这里必须使用p[property]的形式来调用对象属性,因为如果使用p.property的方式,js会在p对象里寻找名为property的属性,得到undefined
document.write(property+"属性的值是"+p[property]+"<br/>");
// 运行结果
// name属性的值是wang
// age属性的值是24
// show属性的值是function (){ document.write("此人年龄: "+this.age+"此人姓名: "+this.name+" "); }
}
8.js对象、类的属性和方法都可以任意添加
为某个类添加属性的方式是:类名.prototype.属性名=sth;
为某个类添加方法的方式是:类名.prototype.方法名=function(){};
应该尽量避免在某个类中直接定义方法,因为这可能造成内存泄漏和闭包,prototype的方式让程序更安全,并提高了性能;
如果在类中直接定义一个方法,那么每创建一个该类的新对象,在同时也会创建一个内置方法的对象,容易造成内存泄漏;
通过prototype属性为类添加方法,让所有实例对象都能够共享该方法
var Person=function(){
var s="secret";
this.info=function(){
return s;
}
}
var p=new Person();
var s=p.info();
alert(s);//secret
Person.prototype.test=function(){
alert("p的新方法");
}
p.test();
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。