1.前言
最近写了个微信小游戏,于是学习了一下JavaScript,作为一门动态语言,对于习惯C++和C#这样的静态语言的我,JavaScript有很多让人非常不舒服的地方,比如定义一个对象的成员变量:
C++/C#:
class myclass{
int memeber;
}
而在JavaScript里:
function myclass(){
this.name = ''
}
或者:
class myclass{
constructor(){
this.name=''
}
}
更别提需要用闭包来实现的private特性,这在读别人的代码时太令人费解了,好在习惯以后还可以接受,并且在写代码时确实非常快(但并不安全,当然use strict可以稍微提升安全性)。
2.JavaScript中的参数传递
首先,对于Number这样的值类型,JavaScript中的参数传递和C++/C#是一致的,即仅传递值,函数内部是局部变量,不会改变外部的值。那么如果我需要用函数改变外部参数的时候该怎么办呢?比如一个swap函数:
function swap(x,y){
let t = x
x = y
y = t
}
如上面的函数是无法进行有效的交换的,在C++里我们可以用&符号来传递一个引用,C#有ref关键字,而JavaScript是没有这些东西的,一个办法是利用返回值,将结果作为数组返回,然后在外部赋值一次:
var x=1,y=2
function swap(x,y){
return [y,x]
}
var swaped = swap(x,y)
x = swaped[1]
y = swaped[0]
当然你可以利用DOM,做一个很别扭的trick来实现表现上类似C++的swap函数,但是在如微信小游戏这样的场景下并不原生支持DOM,而且那种写法确实很奇怪:
function swap($a,$b)
{
var temp=eval($a);
eval($a+"="+$b);
eval($b+"=temp");
}
var a=3,b=4;
swap("a","b");
document.write(a+" "+b);
事实上JavaScript是无法实现一个类似C++的swap函数的,所以我们只能用稍微繁琐一些的方法来实现,另外两个办法一是使用数组:
var arr = [1,2]
function swap(_arr){
let t = _arr[0]
_arr[0] = arr[1]
arr[1] = t
}
另外一个是使用对象:
var obj = {}
obj.x = 1
obj.y = 2
function swap(_obj){
let t = _obj.x
_obj.x = _obj.y
_obj.y = t
}
事实上,JavaScript中的数组也是一个对象,所以这两种方法本质上是一样的,也说明了JavaScript中的对象作为参数时是进行的引用传递。
即:JavaScript中参数传递时基本类型的传递是值传递,对象的传递是引用传递。
3.JavaScript中的引用传递
虽然说JavaScript中的对象是引用传递,可是跟C++的引用却又是不同的,比如:
var x={}
x.name = 'test'
function test(t){
t = {}
t.name = 'test2'
}
test(x)
如上代码,x.name的值仍为'test',而C++,哦C++的引用是不能指向新的对象的,C#可以,但是C#分两种情况:加ref关键字和不加的,JavaScript的行为和C#中不加ref关键字时传递对象的行为是一致的。即这个所谓的引用更像是一个指针,指向和参数的对象同一块内存地址,在上面的例子中,调用t={}时,t指向的就是一块新的内存地址了,和传入参数完全无关。
以上就是关于JavaScript中对象和函数参数的总结,欢迎指正。