JavaScript修改作用域外变量的方法


Posted in Javascript onMarch 25, 2016

1.今天在看JavaScript学习指南的时候做的课后习题,也因此详细的对函数的传入参数进行比较深入的研究.

题目如下:

函数如何才能修改其作用域之外的变量?编写一个函数,由1~5的数字组成的数组作为参数,调用该函数后将把其中的数字项替换为相应的字符串表示形式.

需要注意知识点:

在JavaScript中函数参数的传递,对于基于原始值的参数进行值传递(数字,字符串,布尔值),函数中的修改不会影响实际参数值.而传递给函数的参数而言,对象是一个引用,对其的修改的将会反映在主调程序中.<-但是,会有这样的情况,如下

var outer_number = ;
var outer_boolean = true;
var outer_array = [,,];
var outer_object = {test:""};
function display(num,bool,arr,obj){
console.log("number:"+num+"\nboolean:"+bool+"\narray:"+arr+"\nobject:"+obj.test);
}
function test(num,bool,arr,obj){
display(num,bool,arr,obj);//num=,bool=true,array=[,,],object.test=
num = ;
bool = false;
arr[] = ;
obj.test = "";
display(num,bool,arr,obj);//num=,bool=false,array=[,,,],object.test=
arr = [,,];
obj = {test:""};
display(num,bool,arr,obj);//num=,bool=false,array=[,,],object.test=
}
test(outer_number,outer_boolean,outer_array,outer_object);
display(outer_number,outer_boolean,outer_array,outer_object);//num = ,bool=true,array=[,,,],object.test=

在上面代码中我们创建了4个全局变量,类型分别为数字,布尔值,数组,对象.2个函数,display和test.

display执行了4次,分别结果如下:

"number:2
boolean:true
array:1,2,3
object:122"<-传入函数时的值

"number:0
boolean:false
array:1,2,3,3
object:134"<-执行更改

"number:0
boolean:false
array:3,2,1
object:133"<-重新赋值

"number:2
boolean:true
array:1,2,3,3
object:134"<-函数执行完毕后

可以看出我们对数组和对象的重新赋值并没有成功,如果按引用传递,那么我们应该也对全局变量的数组和对象重新赋值修改了呀.
其实JavaScript中所谓的按引用赋值并不是真正意义上的按引用复制,准确说应该是按共享传递.也可以叫按对象传递,按对象共享传递(call by sharing).

在这个按共享传递的条件下,我们获取的引用可以说只是实参引用的副本,它和我们经常说的按引用传递的最大差别就在于我们在对引用副本的赋值不会影响实参的值,正如我们上面那样做的那样,赋值操作是不可行的.

当然我们从对象类型和基本类型两方面看,对象是可变的而基本类型是不可变的(注意!字符串修改其实是返回的新的字符串),所以按共享传递对于基本类型来说也是符合按共享传递的.

总结一下:

JavaScript中,基本类型和对象都按共享传递(call by sharing),但是由于JavaScript的基本类型的不变性,基本类型按共享传递与按值传递没有任何区别,而对象按共享传递.

按共享传递(call by sharing):传递的是实参引用的副本,我们对引用副本的赋值不影响实参的值,但是可以使用引用副本去修改引用的内容.详细的wiki地址

函数对传入的参数:

1.基本类型,按值传递(或者也可以说按共享传递),内部赋值修改都不影响主调程序

2.对象类型,按共享传递,传入的为实参引用的副本,内部对该引用的赋值无效,对对象属性的赋值修改有效.

大概就是这么理解了,假如有什么地方我犯了什么错误,也希望能被指出来.

下面单独拉出JavaScript作用域

任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

全局作用域(Global Scope)

在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:

(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域,例如:

var authorName="山边小溪";
function doSomething(){
var blogName="梦想天空";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(authorName); //山边小溪
alert(blogName); //脚本错误
doSomething(); //梦想天空
innerSay() //脚本错误

(2)所有末定义直接赋值的变量自动声明为拥有全局作用域,例如:

function doSomething(){
var authorName="山边小溪";
blogName="梦想天空";
alert(authorName);
}
doSomething(); //山边小溪
alert(blogName); //梦想天空
alert(authorName); //脚本错误

变量blogName拥有全局作用域,而authorName在函数外部无法访问到。

(3)所有window对象的属性拥有全局作用域

一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等。

1. 局部作用域(Local Scope)  

和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域,例如下列代码中的blogName和函数innerSay都只拥有局部作用域。

function doSomething(){
var blogName="梦想天空";
function innerSay(){
alert(blogName);
}
innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错误

Javascript 相关文章推荐
JQuery将文本转化成JSON对象需要注意的问题
May 09 Javascript
js预载入和JavaScript Image()对象使用介绍
Aug 28 Javascript
node.js中的path.extname方法使用说明
Dec 09 Javascript
ECMAScript 5中的属性描述符详解
Mar 02 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
Sep 27 Javascript
jQuery EasyUI Tab 选项卡问题小结
Aug 16 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
May 01 Javascript
浅谈微信JS-SDK 微信分享接口开发(介绍版)
Aug 15 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
Nov 29 Javascript
Javascript作用域和作用域链原理解析
Mar 03 Javascript
Vue实现点击导航栏当前标签后变色功能
Aug 19 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 Vue.js
JavaScript 2048 游戏实例代码(简单易懂)
Mar 25 #Javascript
JavaScript入门系列之知识点总结
Mar 24 #Javascript
JS实现支持Ajax验证的表单插件
Mar 24 #Javascript
拥有一个属于自己的javascript表单验证插件
Mar 24 #Javascript
jquery zTree异步加载、模糊搜索简单实例分享
Mar 24 #Javascript
js+css实现select的美化效果
Mar 24 #Javascript
基于jQuery Ajax实现上传文件
Mar 24 #Javascript
You might like
我的论坛源代码(六)
2006/10/09 PHP
常用的php ADODB使用方法集锦
2008/03/25 PHP
php 网上商城促销设计实例代码
2012/02/17 PHP
php smtp实现发送邮件功能
2017/06/22 PHP
PHP+Oracle本地开发环境搭建方法详解
2019/04/01 PHP
推荐30个新鲜出炉的精美 jQuery 效果
2012/03/26 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
IE6浏览器中window.location.href无效的解决方法
2014/11/20 Javascript
使用Raygun来自动追踪AngularJS中的异常
2015/06/23 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
2017/08/22 Javascript
详谈vue+webpack解决css引用图片打包后找不到资源文件的问题
2018/03/06 Javascript
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
Javascript confirm多种使用方法解析
2020/09/25 Javascript
JavaScript 防盗链的原理以及破解方法
2020/12/29 Javascript
[00:36]DOTA2上海特级锦标赛 Alliance战队宣传片
2016/03/04 DOTA
python使用正则表达式提取网页URL的方法
2015/05/26 Python
Python实现批量转换文件编码的方法
2015/07/28 Python
Python实现合并同一个文件夹下所有txt文件的方法示例
2018/04/26 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
python对指定字符串逆序的6种方法(小结)
2020/04/02 Python
python zip,lambda,map函数代码实例
2020/04/04 Python
Python操作word文档插入图片和表格的实例演示
2020/10/25 Python
Window10上Tensorflow的安装(CPU和GPU版本)
2020/12/15 Python
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
英国最大的在线时尚眼镜店:Eyewearbrands
2019/03/12 全球购物
英国领先的露营和露营车品牌之一:OLPRO
2019/08/06 全球购物
一些Unix笔试题和面试题
2013/01/22 面试题
几道Web/Ajax的面试题
2016/11/05 面试题
廉洁自律承诺书
2014/03/27 职场文书
python 逐步回归算法
2021/04/06 Python
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS