js之变量和作用域
JS的变量和其他语言的变量有很大区别。JS变量时“松散型”的,决定它只是在特定时间用于保存特定的一个名字而已。
由于不存在变量要保存何种数据类型,变量的值和其数据类型可以在脚本的生命周期内改变。
JS两种数据类型:
基本类型:(存在栈内存,比如:Number、Null、Boolean、Undefined和String)
引用类型:(存在堆内存中,Object类型),他的引用地址(指针)存在 栈空间内
PS(*重点*):
1、在JS中,string 字符串类型是 值类型(基本类型),不是引用类型;;这是和其他语言不同的地方
2、基本类型存在栈内存中,他们所占的大小是固定的大小
1、动态属性
只有引用类型可以添加动态属性,,基本类型不能添加动态属性:原因:因为引用类型存在 堆 内存中,大小不固定,可以动态添加;;但是基本类型存在 栈 内存中,,内存大小固定,所以不能 动态添加属性
var box =new Object();//定义一个引用类型变量
box.Name='小明';
alert(box.Name); var num='shit';
num.Name='demo';//基本类型是 不能添加属性的(因为他是存在栈中的,大小是固定的,所以不能添加属性扩展大小)
alert(num.Name);//undefined
2、赋值对象
1》基本类型的复制:
基本类型对象复制,复制的是值。
2》引用类型的对象复制
引用类型对象的复制,复制的是地址。
var box =new Object();
box.Name='demo'; var box2=box;
box2.Name='shit';
alert(box.Name);//shit 因为box和box2指向 堆里 同一个 内存空间,所以 box2改变的是 堆空间中 数据,所以box在取得时候是改变过的数据了
3、传递参数
注意:JS中传递参数是 “按值” 传递的,不是 按 “引用” 传递的。
function box(obj){ //记住:这也是按值传递,只不过传递的参数是引用类型,,但是不是按引用传递,,按引用传递,比如c#里的ref 和out/c中&
obj.name='demo';
} var p=new Object();
box(p); //因为 按值传递:传递的是 地址,所以 会为p增加name属性并赋值
alert(p.name);
PS:传递引用类型的参数和按“引用”传递 是不同的概念。
4、变量检测
在之前的学习中,我们知道区分不同类型的数据可以使用 typeof;;但是如果 对 引用类型的数据 在进一步区分(例如:数组、null、正则表达式都是引用类型) 就要使用instanceof
var box1=new Object(); //引用类型 var box2=/box/; //正则表达式 var box3=[,];//数组 alert(box1 instanceof Object); //true
alert(box2 instanceof RegExp); //true
alert(box3 instanceof Array); //true //PS:instanceof不能对 基本类型进行检测, 因为即使正确 也会返回false var box4='demo';
alert(box4 instanceof String); //false
var box5=new String('demo');//使用 new 修饰符的 方式创建的 就可以 使用instanceof 进行检测了
alert(box5 instanceof String); //true
5、执行环境及作用域
执行环境:
定义变量或函数 有权访问其他数据,决定他们的一切行为。
全局执行环境被认为最外层的执行环境,在 web 中被认为是 window。
注意点:
1》当执行环境中所有的代码执行完成之后,该环境就会被销毁,包括在其中的所有的变量和函数也会被销毁。但是如果是全局环境下,就需要整个程序执行完毕之后,才会销毁(也就是网页关闭之后)
2》每个执行换进都会有一个对象与之关联对应,就比如全局执行环境对应window。局部执行环境也会(一个函数的{}内部)有一个与之对应的对象,只不过是我们不能访问它,但是 解析器会在处理数据是后台使用它们。
下面是非常经典的例子,非常容易弄错的:
function a(b){
alert(window.a);
alert(b);
function b(){ //此处的b 既是 当前执行环境的对象的属性,,还是 自己这个函数下的执行环境下的属性;;都能被访问到
alert(b);
}
b();
}
a('shit');
总结说明:在前面的“Function原型”中提到了,每一个Function函数都是一个对象。。在执行的一瞬间,会产生一个Active Object(简称:AO)的对象,对于全局执行环境就是对应的window,局部执行环境就是AO。所有的变量(包括传进来的参数和自己定义的变量)和函数都会生成为AO的“属性”,所以这就是为什么上面传进来的参数b会被 下面的 函数b 替代掉(因为都是AO的b属性),后面的同名属性会覆盖前面的。
6、{} 没有起到限制作用域的:if 和 for
这种时候,就要对使用完的对象 进行 手动的 清除,实现 垃圾回收。
if(true){
var box ='demo';
} alert(window.box);// demo 结果: 在 全局的 执行环境下 也能 访问到 box box=null; //将引用释放,等待垃圾回收。 for(var i=;i<;i++){
var num ='shit';
}
alert(i); //10 结果: 在 全局 执行环境下 能被 访问到
alert(window.num);//shit 结果: 在 全局的 执行环境下 也是能 访问到 num的 function sum(num1){
var num2 ='lee';//在 函数内(sum 执行环境下) 用 var 定义的变量时 局部变量
//将 var 去掉 直接定义的 变量时 全局变量
num3 ='xiao'; //这种方式最好不要用,因为 可能会在 下面引发很多问题;;;如果真的想用全局变量,那就直接在外面定义 全局变量就可以了
} sum();
alert(num2); //报错:num2 is not defined
alert(num3); //xiao
if和for的演示代码
7、变量的搜索查询
沿着 “作用域链” 向上 查询的。
var box ='Lee';
function getBox(){
return box;
} alert(getBox()); //Lee function getBox2(){
var box ='xiao';
return box; //在返回 box的值的时候会 向上搜索box的值,现在 SetBox2()作用域内搜索 局部变量,如果没有就 到 SetBox2()的上一层 作用域去寻找,如果一直没有,直到最后带 全局作用域去寻找,如果在找不到就会报错。。只要 找到就 直接返回。
}
alert(getBox2()); //xiao
8、JS中的垃圾回收
JS 是 自动进行 垃圾回收的,但是 自己 使用过的 引用类型对象,如果不想使用了,可以 设置成null,那么 一会就会被垃圾回收了,提高性能
var box ={};
box.name='xiaoming';
//以后就不想使用了
box =null; // 引用被清除了,等待 垃圾回收器 清理
js之变量和作用域的更多相关文章
- Js中变量的作用域
一.理解函数作用域需要理解以下几点: 1.函数变量的作用域有全局变量和局部变量两种,全局变量写在函数的最前面,局部变量写在函数体内,局部变量省略了var 也就默认成为了全局变量! 2.函数 ...
- 有关js的变量、作用域和内存问题
来自<javascript高级程序设计 第三版:作者Nicholas C. Zakas>的学习笔记(四) js共有5种基本数据类型:Undefined.NULL.Boolean.Numbe ...
- JS中变量、作用域的本质,定义及使用方法
全局作用域和局部作用域 全局作用域 局部作用域:函数作用域 全局作用域在全局和局部都可以访问到,局部作用域只能在局部被访问到 var name="cyy"; function fn ...
- JS:变量的作用域
1.作用域: 指一个变量它在哪些代码范围能够被使用,这些地方就是变量的作用域 JS中的两种作用域: 1.全局作用域.2.函数作用域 2.在es5中 函数的代码块内部的代码 可以访问形参变量 也可 ...
- Js的变量、作用域与内存
变量.作用域与内存 1 .原始值与引用值 Undefined.Null.Boolean.Number. String和Symbol.保存原始值的变量是按值(by value)访问的 引用值是保存在内存 ...
- js里变量的作用域
一.在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域.也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的.但是,如果该变量是定义在if或者for这样的代码块 ...
- js中变量的作用域、变量提升、链式作用域结构
一:作用域 在ES6之前,javascript没有块级作用域(一对{}即为一个块级作用域),只有全局作用域和函数作用域(局部),因此,对应的有全局变量和局部变量.在函数内部可以访问到全局变量,但在函数 ...
- 关于JS中变量的作用域-实例
先看问题,如下,自己运行一下吧! if (!('_qyzA' in window)) { var _qyzA = 1; } alert(_qyzA);//undefined 分析:首先,所有的全局变量 ...
- js基础——变量、作用域、内存
1.new关键字创建的是引用类型: eg. var box = new Object(); box.name = "Linda";//引用类型添加属性没问题 al ...
随机推荐
- ASP.NET-----Repeater数据控件的用法总结(转)
一.Repeater控件的用法流程及实例: 1.首先建立一个网站,新建一个网页index.aspx. 2.添加或者建立APP_Data数据文件,然后将用到的数据库文件放到APP_Data文件夹中. 3 ...
- 一分钟学会(一):.NET之正则表达式
本文介绍正则表达式在.NET中的基本应用,代码简单粗暴,实例浅显易懂,让你一分钟快速上手正则(大鸟请略过). 本文为入门文章,很多时候我们只是忘记了语法,这也可作为一个快速查询的参考. 如果想深入学习 ...
- URL重写以后发布到IIS找不到页面
1.读取必须勾选,否则无法加载资源文件(img,css等) c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
- 学生信息管理系统应用ios源码iPad版
学生信息管理系统应用iPad版,该应用源码比较完整的,而且也很详细,这也是一款学校用的学生和老师管理系统,里面涉及到了很多ipad常用的控件,操作和数据存储. <ignore_js_op> ...
- sql取字段特定符号的前/后
declare @canshu varchar(200)set @canshu='24§咨询客户'--某符号之后的字段内容select substring(@canshu,charindex('§', ...
- 深入浅出HTML与XHTML的区别
HTML(HyperText Markup Language,超文本标记语言)最早的HTML官方正式规范,是1995年IETF(Internet Engineering Task Force,因特网工 ...
- linux下securetty文件
“/etc/securetty”文件允许你规定“root”用户可以从那个TTY设备登录.登录程序(通常是“/bin/login”)需要读取“/etc/securetty”文件.它的格式是:列出来的tt ...
- winfrom之动态控件生成以及保存动态空间的数据
前些天要完成一个winform程序,里面涉及到动态控件的添加以及保存动态空间中数据的保存,效果如下 初始化时: 点击添加阶梯价后:(点击一下,动态添加一行) 那么接下来,我们就具体的讲下代码实现: 首 ...
- 关于VS2012下安装破解文件Visual Assit X的一点说明
今天在使用Visual Studio 2012的时候,编写代码的助手Visual Assit X突然提示我说,试用期已过,要求我输入一个注册码,我靠,这货不是几个月前已经破解了吗,怎么今天傻不愣登的提 ...
- UltraEdit中使用正则表达式
正则表达式 (UltraEdit Syntax): % 匹配行首 - 表明要搜索的字符串一定在行首. $ 匹配行尾 - 表明要搜索的字符串一定在行尾 ? 匹配除换行符外的任一单个字符. * 匹配任意个 ...