js设计模式学习之面向对象的javascript(一)
2013-05-05 11:28
363 查看
声明:此学习笔记主要是学习《Pro JavaSript Design Patterns》(中文名:JavaScript设计模式)一书所写,另外参考《JavaScript高级程序设计》(第三版),接触javascript半年了,代码写多了却感觉越写越糟糕,因此想细心的研究下设计模式,因为不是一个很有耐心的人,对于一件事坚持不了多久,所以想了一个办法,申请了一个博客,希望能坚持记录学习点滴,督促自己把这件事继续下去。
javascript是弱类型的语言,定义变量时不必声明类型,但这并不意味着变量没有类型,一个变量可以属于几种类型之一,这取决于变量包含的数据。
javascript的三种原始类型:布尔型、数值型、字符串类型(不区分整数和浮点数是js与众多语言不同的特点之一)。
对象类型:一种复合的数据类型。(数组算是一种特殊的对象,它包含着一批值得有序集合)
空类型(null)和未定义类型(undefined)。
原始的数据类型是按值传送,其他数据类型是按引用传送的。
js函数的参数传递:ECMAScript中所有的函数的参数都是按值传递的,就是说把函数外部的值复制给函数内部的参数。
访问变量有按值和按引用两种方式,但是函数的参数传递只能按值传递。
下面举几个例子来验证上面这句话:
首先对于原始类型的传递:
var i=10;
function addself(i){
i+=i;
console.log(i); //20
}
addself(i);
console.log(i); //10
很明显对于原始类型的参数传递,与c、c++等语言都是类似的,下面我们看一下对象类型
var obj={
name:"flyhorse"
};
function changeName(o){
o.name="horse";
}
changeName(obj);
console.log(obj.name); //horse
上面的例子似乎跟其他语言的引用类型的传递如出一辙,并不能证明js的函数对于引用类型也是按值传递的。
下面我们修改一下上方的例子:
var obj={
name:"flyhorse"
};
function changeName(o){
o=new Object();
o.name="fly";
console.log(o.name); //fly
};
changeobj(obj);
console.log(obj.name); //flyhorse
如果说函数参数的引用类型是按址传递的话,那么上方的例子,我们将obj的地址传递给了o,在函数的内部我们重新创建了一个对象,并且将o指向这个对象,为对象添加了属性name为“fly”,函数执行完后,我们的全局的obj应该也会改变,name属相打印出应该是“fly”,但是为什么结果是打印出“flyhorse”呢?
我们再重新分析一下:我们将全局的obj对象的地址,传递函数的参数o,其实是我们将obj的地址,复制了一个副本给了参数o,而参数o呢,其实是函数内部的局部变量(或者说是函数的arguments对象的一个元素),如果能够理解o是函数内部的局部变量那么结果就很好理解了,我们在函数内部对于o变量的一切操作,会在函数作用域退出时被清理干净(当然也会将局部变量o清除干净),所以当函数执行完毕后,我们的全局的obj对象没有收到任何影响。
这样我们再来看第二个例子也就知晓了,我们将全局的obj对象的地址值,复制了一个副本传递给了函数的参数o(函数的局部变量),此时函数的局部变量o和全局变量obj引用的其实是堆里的同一个对象,而且还是全局的对象,此时我们通过变量o修改的全局对象的属性当然也会反映到全局中。
所以说我们并不能因为在局部作用域中修改的对象会在全局作用域中反应出来,就简单的认为参数是按照引用传递的。
javascript是弱类型的语言,定义变量时不必声明类型,但这并不意味着变量没有类型,一个变量可以属于几种类型之一,这取决于变量包含的数据。
javascript的三种原始类型:布尔型、数值型、字符串类型(不区分整数和浮点数是js与众多语言不同的特点之一)。
对象类型:一种复合的数据类型。(数组算是一种特殊的对象,它包含着一批值得有序集合)
空类型(null)和未定义类型(undefined)。
原始的数据类型是按值传送,其他数据类型是按引用传送的。
js函数的参数传递:ECMAScript中所有的函数的参数都是按值传递的,就是说把函数外部的值复制给函数内部的参数。
访问变量有按值和按引用两种方式,但是函数的参数传递只能按值传递。
下面举几个例子来验证上面这句话:
首先对于原始类型的传递:
var i=10;
function addself(i){
i+=i;
console.log(i); //20
}
addself(i);
console.log(i); //10
很明显对于原始类型的参数传递,与c、c++等语言都是类似的,下面我们看一下对象类型
var obj={
name:"flyhorse"
};
function changeName(o){
o.name="horse";
}
changeName(obj);
console.log(obj.name); //horse
上面的例子似乎跟其他语言的引用类型的传递如出一辙,并不能证明js的函数对于引用类型也是按值传递的。
下面我们修改一下上方的例子:
var obj={
name:"flyhorse"
};
function changeName(o){
o=new Object();
o.name="fly";
console.log(o.name); //fly
};
changeobj(obj);
console.log(obj.name); //flyhorse
如果说函数参数的引用类型是按址传递的话,那么上方的例子,我们将obj的地址传递给了o,在函数的内部我们重新创建了一个对象,并且将o指向这个对象,为对象添加了属性name为“fly”,函数执行完后,我们的全局的obj应该也会改变,name属相打印出应该是“fly”,但是为什么结果是打印出“flyhorse”呢?
我们再重新分析一下:我们将全局的obj对象的地址,传递函数的参数o,其实是我们将obj的地址,复制了一个副本给了参数o,而参数o呢,其实是函数内部的局部变量(或者说是函数的arguments对象的一个元素),如果能够理解o是函数内部的局部变量那么结果就很好理解了,我们在函数内部对于o变量的一切操作,会在函数作用域退出时被清理干净(当然也会将局部变量o清除干净),所以当函数执行完毕后,我们的全局的obj对象没有收到任何影响。
这样我们再来看第二个例子也就知晓了,我们将全局的obj对象的地址值,复制了一个副本传递给了函数的参数o(函数的局部变量),此时函数的局部变量o和全局变量obj引用的其实是堆里的同一个对象,而且还是全局的对象,此时我们通过变量o修改的全局对象的属性当然也会反映到全局中。
所以说我们并不能因为在局部作用域中修改的对象会在全局作用域中反应出来,就简单的认为参数是按照引用传递的。
相关文章推荐
- js设计模式学习之面向对象的javascript(二)——接口
- js设计模式学习之面向对象的javascript(三)--原型式继承
- javascript学习笔记(九) js对象 设计模式
- JS学习笔记——面向对象,设计模式
- 【JS设计模式】JavaScript特性
- 学习JavaScript设计模式(封装)
- Android设计模式学习(包含Java设计模式)-面向对象的六大原则-AJDesignMode01
- javascript面向对象和设计模式
- 学习JavaScript设计模式(三)
- [设计模式学习笔记一][面向对象七大设计原则]
- [js高手之路]面向对象+设计模式+继承一步步改造简单的四则运算
- 韩顺平_轻松搞定网页设计(html+css+javascript)_第23讲_js三大流程控制(顺序流程、分支控制、循环控制)_js调式技巧_学习笔记_源代码图解_PPT文档整理
- 学习JavaScript设计模式之中介者模式
- JavaScript设计模式学习——Basic Function
- JavaScript 设计模式学习 Factory
- Javascript 设计模式学习之三 Singleton(单例)模式
- js设计模式的学习
- 【JS设计模式】JavaScript特性
- 【学习笔记javascript设计模式与开发实践(组合模式)----10】
- 学习JavaScript设计模式之单例模式