js-变量、作用域和内存问题,引用类型

变量、作用域和内存问题

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的随机数

时间: 2024-08-06 20:07:23

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

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

JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. 一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈

javascript变量作用域与内存

第四章 变量作用域与内存基本类型 5种Undefined Null Boolean Number String 两种变量类型 基本类型与引用类型注意:String 再其他语言中是引用类型,再javascri中为基本类型即:这五种基本类型是按值访问的 引用类型是按照引用访问的 动态的属性对于一个引用类型,一个引用变量被赋值后,可以为其添加属性,也可以删除与修改其属性var o = new object();o.name = "qi"; //可以为引用变量添加属性 变量的复制基本类型的复制

js变量作用域

? 1 2 3 4 5 6 7 8 9 10 for(var i =0;i<100;i++)   {        } alert(i);//100 if(true){     var i="91d";   } alert(i);//91d ? 1 2 3 4 5 6 function add(ad1,ad2){   sum=ad1+ad2;   return sum;//如果没有用var声明局部变量,会提升为全局的变量 } alert(add(3,5)); alert(&quo

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

今天的这个文章题目名称甚是让人会突发异想.JS变量作用域是务必需要搞懂的,单从面试过程就会让面试者烧脑壳.所以,我们还是写一篇关于JS变量作用域的技术专题,让所有小伙伴能够借此文章去整理JS的基础学习.说不定很多人会比我理解这方面基础知识有更好地见解 黄金守则第一条: JS没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到 <!doctype html> <html lang="en"> &

JavaScript变量作用域和内存问题(js高级程序设计总结)

1,变量 ECMAScript和JavaScript是等同的吗?个人认为是否定的.我的理解是这样的,ECMAScript是一套完整的标准或者说协议,而JavaScript是在浏览器上实现的一套脚本语言.也就是说,ECMAScript是JavaScript的父类标准.JavaScript是ECMAScript的具体实现.所有ECMAScript定义的数据类型或者语言特性实际上都是伪代码的形式规定的.当然如果可以,ECMAScript也可以有服务器实现,单片机实现(不一定恰当).如果说ECMAScr

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

变量.作用域和内存问题 执行环境共有两种类型——全局和局部 作用域链会加长,有两种情况:try-catch语句的catch块,with语句. javascript没有块级作用域,即在if,for循环中的变量,在块结束后,并不会被销毁. 最好能手工断开原生javascript对象与DOM元素之间的连接. Object类型 创建Object实例有两种方式:new 操作符后跟Object构造函数即new Object(),对象字面量表示法即用{}表示. 可使作方括号表示法来访问对象的属性,将要访问的属

javaScript的闭包 js变量作用域

js的闭包 js的变量作用域: var a=90; //定义一个全局变量 function test(){ a=123; //使用外层的 a变量 } test(); document.write("a="+a); var a=90; //定义一个全局变量 function test(){ var a=123; //定义一个局部变量 } test(); document.write("a="+a); a=90; //没有var ,就会试着去找(父函数 的 a),如果找

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

上一章 JS执行上下文.变量提升.函数声明 传送门:https://segmentfault.com/a/11... 本次我们主要讲讲变量作用域和闭包变量作用域:顾名思义:变量起作用的范围.变量分为全局变量和局部变量.全局变量:在任何地方都能用,在所有函数之外.局部变量:只能在定义它的函数中,以及它的子函数中使用. 当前作用域没有定义的变量,称为自由变量. 举例子: <!DOCTYPE html> <html> <head> <title>dsfg</

JS变量+作用域

基本类型-栈内存 保存基本类型的变量保存的是值本身 引用类型-堆内存 保存引用类型的变量保存的并不是对象本身,而是一个指向该对象的引用地址 引用类型判断对象是否相等 function equalObjs(a, b) { for (var p in a) { if (a[p] !== b[p]) return false; } return true; } console.log(equalObjs(xm, xh)); 引用类型判断数组是否相等 function equalArrays(a, b)