变量、作用域和内存问题

1、变量可能包含两种不同数据类型的值;基本类型值以及引用类型值;引用类型值保存的是内存中的对象

2、对象是按值传递的,

function setName(obj){

obj.name="zhang";

obj=new Object();

obj.name="hui";

}

var person=new Object();

setName(person);

alert(person.name);     //zhang

//在函数中将person对象作为参数传给setName,

在函数中又创建了一个新的对象,并且重新对name赋值,

但在外部访问person.name的时候,结果还是zhang,因为函内部重写obj

的时候,这个变量引用就是一个局部变量,在函数执行介绍后就被立即销毁

3、如果变量值是一个一个对象或者null,typeOf操作符会返回一个object。

如果变量是给定引用类型的实例,instanceof操作符会返回true:

result=variable  instanceof  constructor    -----检测对象

eg:alert(person instanceof Object);//变量person是Object吗?

alert(colors instanceof Array);//变量colors是Array吗?

在检测一个引用类型值和Object构造函数时,instanceof会始终返回true,检测基本数据类型的时候会返回false;

4、执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。执行环境中所有代码执行完毕后,环境被销毁,保存在其中的所有变量以及函数定义也会随之销毁,全局执行环境要直到应用程序退出才销毁,例如关闭网页或浏览器

5、内部环境可以通过作用域链访问所有外部环境,外部环境不能访问内部环境中的任何变量以及函数。任何环境都不能通过向下搜索作用域链而进入另一个执行环境。

6、初始化变量时,没有添加var声明,该变量会自动添加到全局环境中

7、如果在函数的局部变量中有一个同名的变量,会使用局部变量而不会再向上查找

8、在IE以及Opera7以上的版本中,window.CollectGarbage()方法会立即执行垃圾收集

9、基本数据类型在内存中占据固定大小的空间,因此被保存在栈内存中

引用类型的值是对象,保存在堆内存中

引用类型:

1、

第一种方式:

var person=new Object();

person.name="zhang";

person.age=29;

第二种方式:

var person{

name:"zhang",

age:29

};

//在age之后不能有逗号,因为age是最后一个属性

第三种方式:

var person{

"name" : "zhang",

"age" : 29,

5 : true

};

//这里的数值属性会自动转化为字符串

第四种方式:

var person={}; -----与new Object()相同

person.name="zhang";

person.age=29;

2、访问对象属性:

alert(person[“name”]);

alert(person.name);

//方括号语法的优点是可以通过变量来访问属性

eg:var propertyName="name";

alert(person[propertyNmae]);

如果属性名中包含会导致语法错误的字符,或者属性名中使用的是关键字或保留字,

也可以使用方括号表示法

eg:person["first name"]="zhang";

//first name中包含一个空格,不能使用点表示法,属性名中包含非字母非数字的,

可以使用方括号表示法对它进行表示

3、Array类型

A: var colors=new Array();

var colors=new Array(20);  ----length为20

var names=new Array("Greg");

var colors=["red","blue","green"];

var names=[];----创建一个空数组

B:length属性不是只读的,长度为3,将长度属性值设为2的时候,会移除最后一项,当再访问第三项的时候就会显示undefined

使用length在数组末尾添加,

Eg:var colors=["red","blue","green"];

colors[colors.length]=“black”;-----在位置3添加一个颜色

colors[colors.length]=“red”;-----在位置4添加一个颜色

C:检测某值是不是数组

If(Array.isArray(value)){}

D:所有对象都有toLocaleString()、toString()、valueOf()方法,其中toString()方法会返回由数组中每个值的字符串拼接而成的以逗号分隔的字符串;valueOf()返回的还是一个数组。

var colors=["red","blue","green"];

alert(colors.toString()); //red,blue,green

alert(colors.valueOf()); //red,blue,green

alert(colors);//red,blue,green

E: var person1={

toLocaleString : function(){

return "zhang";

},

toString : function(){

return "zhang";

}

};

var person2={

toLocaleString : function(){

return "hui";

},

toString : function(){

return "yun";

}

};

var people=[person1,person2];

alert(people);             //zhang,yun

alert(people.toStrinr());      //zhang,yun

alert(people。toLocalleString());   //zhang,hui

//将数组传递给alert的时候,调用了数组的toString方法

F:使用join()方法作为字符串的分隔符:alert(colors.join(”、、”));

G:栈方法:(移除返回项,添加返回长度)

push():添加到数组的末尾,返回修改后数组的长度

pop():从数组末尾移除最后一项,减少数组的length,然后返回移除的项

colors[3]=“black“;----直接添加

H:对列方法:(移除返回项,添加返回长度)

shift()移除数组中的第一项并返回该项,同时将数组长度减1

unshift()方法再数组的前端添加任意多个项并返回新数组的长度

I:重排序方法:reverse()、sort()

reverse()会反转数组项的顺序

sort()默认情况下按升序排列数组项,会调用每个数组项的toString()转型方法,然后比较得到的字符串

J:创建新数组:concat()方法

var colors=colors.concat(”yellow”,[“black” , “brown”]);

基于当前数组中的一或多项创建一个新数组:slice()方法—可以接受一个或两个参数,即返回项的指定位置到指定结束位置(不包括结束位置的项)

var colors=["red","green","blue"];

var colors1=colors.slice(1);    --green,blue

var colors2=colors.slice(0,2);  ----red,green

splice()方法:向数组的中部插入项,返回的是数组

splice(0,2)---要删除的第一项的位置,删除的项数

splice(2,0,”red”,”green”)—起始位置,要删除的项数,要插入的项-----从位置2开始插入

splice(2,1,”red”,”green”)—先删除再添加

K:indexOf()以及lastIndexOf()方法,包含两个参数,一个是要查找的项,还有一个是查找起点位置的索引

indexOf()---从0开始查找

lastIndexOf()----从数组的末尾开始查找

在没找到的情况下返回-1

L:迭代方法:

1)     every():对数组中的每一项运行给定函数,如果该函数是对每一项都返回true,则返回true

2)     filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组

var numbers=[1,2,3,4,5,4,3,2,1]

var filterResult=numbers.filter(function(item,index,array){

return (item>2);

});

alert(filterResult);   //[3,4,5,4,3]

3)     forEach():对数组中的每一项运行给定函数,没有返回值

4)     map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组

var numbers=[1,2,3,4,5,4,3,2,1]

var mapResult=numbers.map(function(item,index,array){

return item;

});

alert(mapResult);

5)     some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true

M:归并方法:reduce()以及reduceRight(),两个方法都会迭代数组的所有项,并且构建一个最终返回的值,接收两个参数,在每一项上调用的函数以及(可选的)作为归并基础的初始值;

函数接收4个值,前一个值,当前值,项的索引,数组对象

reduce()是从数组的第一项开始,逐个遍历

reduceRight()是从数组的最后一项开始,向前遍历到第一项

4、Date类型

A:第一种方法:

//取得开始时间

var start=Date.now();

doSomeThing();

//取得结束时间

var stop=Date.now(),

result=stop -start;

第二种方法:

//取得开始时间

var start=+new Date();

doSomeThing();

//取得结束时间

var stop=+new Date(),

result=stop -start;

5、RegExp类型

var expression =/ pattern / flags ;

//每个正则表达式都可带有一个或多个标志,标明正则表达式的行为

flags可以是g(全局);i(不区分大小写);m(多行模式,到达一行文本末尾时)

6、Function类型

A:

function sum(num1,num2){

return num1+num2;

}

alert(sum(10,10));

var anotherSum=sum;

alert(anotherSum(10,10));

//sum与anotherSum都是指向同一函数,所以anotherSum()可以被调用

sum=null;

alert(anotherSum(10,10));

//将sum设为null,让他与函数“断绝关系”,但anotherSum()还是可以正常调用

B:不仅可以像传参一样将一个函数传递给另一个函数,还可以将一个函数作为另一个函数的结果返回

function getGreeting(name){

return "hello," + name;

}

var result=callSomeFunction(getGreeting,"zhang");

alert(result);     ------"hello, zhang"

C:访问函数的指针而不执行函数,使用不带圆括号的函数名是访问函数的指针,而非调用函数

D:函数内部属性,两个特殊对象:arguments,this。Arguments是保存函数参数,该对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数,eg:阶乘

function factorial(num){

if (num<=1) {

return 1;

}else{

//return num*factorial(num-1)

return num*arguments.callee(num-1)

}

}

E:函数对象属性caller:保存着调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值为null

F:函数的方法:

apply():在特定作用域中调用函数,第一个参数是在其中运行函数的作用域,第二个是参数数组,其中,第二个可以是Array的实例,也可以是arguments对象

function sum(num1,num2){

return num1+num2;

}

function callSum1(num1,num2){

return sum.apply(this,arguments);

}

function callSum2(num1,num2){

return sum.apply(this,[num1,num2]);

}

alert(callSum1(10,10));  ---20

alert(callSum2(10,10));  ---20

call():在特定作用域中调用函数,第一参数是this,第二个参数中,传递给函数的参数必须逐个列举出来

function sum(num1,num2){

return num1+num2;

}

function callSum1(num1,num2){

return sum.call(this,num1,num2);

}

alert(callSum1(10,10));  ---20

F:object构造函数,根据传入值的类型返回相应基本包装类型的实例

var obj=new Object("some text");

alert(obj instanceof String);  //true

将字符串传给Object构造函数,创建String实例

G:Boolean类型:布尔表达式中的所有对象都会被转为true,不建议使用布尔对象

H:Number类型

1)     var num=10;

alert(num.toFixed(2));   //“10.00”

//toFixed(2)表示要显示几位小数,如果数值本身包含的小数位比指定的多,会舍入---将数值格式化为字符串

2)     toExponential ()方法,返回以指数表示法(e表示法),接收一个参数,表示输出结果中的小数位数---将数值格式化为字符串

var num=10;

alert(num.toExponential(1));  //"1.0e+1"

3)     toPrecision()方法会返回一个最适合的格式

I:String类型:

1)     charAt()方法以单字符串的形式返回给定位置的那个字符

var stringValue="hello world";

alert(stringValue.charAt(1));   //"e"

2)     charCodeAt()得到字符编码

var stringValue="hello world";

alert(stringValue.charCodeAt(1));  //"101"

3)     var stringValue="hello world";

alert(stringValue[1]);  //"e"

4)     concat()将一或多个字符串拼接起来,返回拼接得到的新字符串

var stringValue="hello world";

alert(stringValue.slice(3));    //"lo world"

alert(stringValue.substring(3));   //"lo world"

alert(stringValue.substr(3));      //"lo world"

alert(stringValue.slice(3,7));     //"lo w" 第二个参数指定的是子字符串最后一个字符后面的位置,就是说不包括7

alert(stringValue.substring(3,7));   //"lo w"  第二个参数指定的是子字符串最后一个字符后面的位置,就是说不包括7

alert(stringValue.substr(3,7));     //"lo worl"   第二个参数表示返回的字符个数

当传入的值是负值的时候:

var stringValue="hello world";

alert(stringValue.slice(-3));    //"rld"    实际参数=字符串的长度+参数

alert(stringValue.substring(-3));   //"hello world"   将负数参数转为0

alert(stringValue.substr(-3));      //"rld"   将负的第一个参数加上字符串长度,将负的第二个参数转为0

alert(stringValue.slice(3,-4));     //"lo w"

alert(stringValue.substring(3,-4));   //"hel"     将-4转为0,(3,0),较小的作为开始位置,大的作为结束位置

alert(stringValue.substr(3,-4));     //""

5)     从字符串中查找子字符串的方法:indexOf()以及lastIndexOf()方法,返回子字符串的位置,没有找到则返回-1

indexOf()从开头开始查找,lastIndexOf()由末端向前搜索

6)     删除前置以及后缀的空格,返回结果:trim()

7)     字符的大小写转换方法:toLowerCase()以及toUpperCase()

8)     replace():

var text="cat,bat,sat,fat";

var result=text.replace("at","ond");

alert(result);   //"cond ,bat , sat , fat"

var result=text.replace("/at/g","ond");

alert(result);   //"cond , bond, sond, fond"

9)     split()基于指定的分隔符将一个字符串分割为多个子字符串,并将结果放在一个数组中

7、禁止给undefined、NaN、indefinity赋值

8、Math对象:

1)     min(),max()方法,可以接收任意个数值参数

var max=Math.max(2,3,4,5);

alert(max);

***********

var values=[2,3,5,6,7,8];

var max=Math.max.apply(Math,values)

2)     舍入方法:

Math.ceil()执行向上舍入

Math.floor()执行向下舍入

Math.round()执行四舍五入

3)     Math.random()返回一个大于等于0小于1的随机数

js-变量、作用域和内存问题,引用类型的更多相关文章

  1. js 变量 作用域及内存

    由于Javascript是松散型的,所以其变量只是在特定时间用于保存特定值的一个名字而已,并不存在某个变量必须保存某种类型的值的规则,变量的值以及其数据类型都可以在脚本的声明周期内改变 一.基本类型与 ...

  2. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  3. [刘阳Java]_步步窥探JS变量作用域

    今天的这个文章题目名称甚是让人会突发异想.JS变量作用域是务必需要搞懂的,单从面试过程就会让面试者烧脑壳.所以,我们还是写一篇关于JS变量作用域的技术专题,让所有小伙伴能够借此文章去整理JS的基础学习 ...

  4. 精读《javascript高级程序设计》笔记二——变量、作用域、内存以及引用类型

    变量.作用域和内存问题 执行环境共有两种类型——全局和局部 作用域链会加长,有两种情况:try-catch语句的catch块,with语句. javascript没有块级作用域,即在if,for循环中 ...

  5. javaScript的闭包 js变量作用域

    js的闭包 js的变量作用域: var a=90; //定义一个全局变量 function test(){ a=123; //使用外层的 a变量 } test(); document.write(&q ...

  6. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  7. 原型模式故事链(5)--JS变量作用域、作用域链、闭包

    上一章 JS执行上下文.变量提升.函数声明 传送门:https://segmentfault.com/a/11... 本次我们主要讲讲变量作用域和闭包变量作用域:顾名思义:变量起作用的范围.变量分为全 ...

  8. JS变量+作用域

    基本类型-栈内存 保存基本类型的变量保存的是值本身 引用类型-堆内存 保存引用类型的变量保存的并不是对象本身,而是一个指向该对象的引用地址 引用类型判断对象是否相等 function equalObj ...

  9. 解释JS变量作用域的范例

    JS的变量作用域只有两种:全局作用域与函数作用域. 用var声明的变量不能简单的说是属于函数作用域,应该是说属于其最近的作用域. var a = 10; function test(){ var a; ...

随机推荐

  1. Does the OpenSceneGraph have a native file format?

    From OpenSceneGraph-3.0 onwards we have new native file formats based on generic serializers that ar ...

  2. log4j介绍以及使用教程

    一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接 口服务 器.NT的事件记录器.UNIX Syslog ...

  3. iOS应用架构谈(二):View层的组织和调用方案(上)

    OS客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来回答iOS应用架构中的种种问题,本文是其中的第二篇,主要讲View层的组织和调用方案.上篇主要讲View层的代码结构. ...

  4. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  5. Qt5_简易画板_详细注释

    代码下载链接:  http://pan.baidu.com/s/1hsc41Ek 密码: 5hdg 显示效果如下: 代码附有详细注释(代码如下) /*** * 先新建QMainWindow, 项目名称 ...

  6. C#索引器一

    索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...

  7. 将rabbitmq整合到Spring中手动Ack

    如果要手动ack,需要将Listener container 的 acknowledge 设置为manul,在消费消息的类中需实现ChannelAwareMessageListener接口. over ...

  8. Runtime.getRuntime().exec()

    Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象 的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实 ...

  9. C#回顾 - 2.NET的IO:Path、File、FileInfo、Directory、DirectoryInfo、DriveInfo、FileSystemWatcher

        1.管理文件系统 一般而言,应用程序都会有保存数据.检索数据的需求. 1.1 使用 path 类来访问文件路径 [path常用的方法]:http://www.cnblogs.com/tangg ...

  10. mysql TIME_WAIT

    http://www.th7.cn/system/lin/201404/53762.shtml http://kerry.blog.51cto.com/172631/105233/ http://ww ...