学习Javascript的一些记忆东西
Posted 朽木大叔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Javascript的一些记忆东西相关的知识,希望对你有一定的参考价值。
1、变量
定义变量使用var关键字,
function test(){ var cc = \'11\'; } test(); alert(cc); //报错 未定义的变量 如果把var 去掉的话,则会弹出11... 这个例子可以解释全局变量和局部变量的使用
2、数据类型:Undefined,Null,Boolean,Number,和String。还有1中复杂的Object,JS不支持任何创建自定义类型的机制
undefind和null都是只有一个值的数据类型,从逻辑角度来看,null值表示一个空对象指针,而这也是使用typeof操作符检测null值会返回object的原因,如果定义变量准备在将来存储对象的话,最好将变量初始化为null,而不是其他的值,这样一来,只要检查null的值就可以知道相应的变量是否已经保存了一个对象的引用:比如:
var car=null; if(car !=null){ //这里边可以对car的对象做一些操作 }
实际上undefined指是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true;
alert(null == undefined) //结果返回true;
Boolean类型是ECMAScript中使用最多的一种类型,该类型只有true和false,这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0,另外True和False是标识符,不是Boolean值,大小写敏感
所有类型的值都可以转化为Boolean值,调用转型函数Boolean(),至于返回的是true还是false,取决于转换值的数据类型以及实际值
数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 ""(空字符串) Number 任何非零数值 0和NaN Object 任何对象 null Undefined 不适用 undefined
javascript 中保存数值的方式,可以保存正零(+0)和负零(-0)正零和负零认为相等。
浮点数的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数,例如:0.1加0.2的结果不是0.3,而是0.3000000000000004。这个小小的舍入误差会导致无法测试特定的浮点数值
if(a + b == 0.3){ alert(" you got 0.3. "); } 在这个例子中,我们测试两个数的和是不是0.3。如果这两个数是0.15和0.25或者是0.05和0.25都不会有问题,而如前边所述,如果这两个数是0.1和0.2,那么测试结果将不会通过,因此,永远不要测试某个特定的浮点数值 关于浮点数值计算会产生舍入误差的问题,这是使用基于IEEE754数值的浮点计算的通病,其他使用相同数值格式的语言也存在这种问题
函数的参数:
函数不介意传递进来多少个参数,也不在乎传递的参数是什么类型。也就是说,即便你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个、甚至不传递参数,而解析器永远不会有什么怨言。之所以会这样,原因是
ECMAscript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过arguments对
象来访问这个参数数组,从而获取传递给函数的每一个参数。
其实arguments对象只是与数组类似(它并不是array的实例),因为可以使用方括号语法来访问它的每一个元素(即第一个argements[0]、arguments[1]),使用length来确定传递过来多少个参数。
fucntion haha(){ alert(arguments.length); } haha(); // 0 haha(1); // 1 haha(1,m,cc); // 3
函数没有重载这个概念,后面的函数会覆盖前面的函数
变量的作用域以及内存的问题:
变量可能包含两种不同数据类型的值:基本类型值(undefind、null、Boolean、Number和String)和引用类型值(object)
其中基本类型是按值访问的,因为可以操作保存在变量中的实际的值。引用类型的值是保存在内存中的对象。与其他语言不同。Javascript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象的时,实际上是操作对象的引用而不是
实际的对象。为此,引用类型的值是按引用访问的。
var num1 = 5; var num2 = num1; num1和num2可以参与任何操作不受影响 var obj1 = new obj(); var obj2 = obj1; obj1.name = \'naicho\'; alert(obj2.name); // naicho 首先,变量obj1保存了一个对象的新实例。然后这个值被赋值到obj2中;换句话说,obj1和obj2都指向同一个对象。这个就是变量的引用问题。
传递参数的时候,按值传递的,对象也是按值传递的
function setName(obj){ obj.name = \'haha\'; } var person = new Object(); setName(person); alert(person.name); //haha 以上代码创建一个对象,将其保存在了变量person中。然后,这个对象被传递到setName函数中之后被复制给了obj。在这个函数的内部,obj和person引用的是同一个对象。换句话说,即使这个对象是按值传递的,obj也会按引用来访问同一个对象。于是,当在函数内部为obj添加name属性的时候,函数外部的person也将有所反映;因为person指向的对象在堆内存中只有一个,而且是全局对象。有很多开发人员错误的认为(包括我):在局部作用域修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的。为了证明对象是按值传递的,我们在看一个例子 function setName(obj){ obj.name = \'haha\'; obj = new Object(); obj.name = \'greh\'; } var person = new Object(); setName(person); alert(person.name); //haha 这个例子有一个例子唯一区别就是,一个代码为obj重新定义了一个对象,重新赋了下name的值,如果person是按引用传递的,那么person就会自动被修改为指向其name属性为greh的的新对象,但是,接下来访问name的值显示仍然为haha,这说明,即使在函数内部修改了参数的值,但原始的引用仍然保持不变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁
声明变量:
使用var声明的变量会自动被添加到最 接近的环境中,在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境是函数环境l;如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境。
基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中。从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;
引用类型的值是变量,保存在堆内存中;包含引用类型值的变量实际上包含的不是对象的本身,而是一个指向该对象的已个指针; 从一个变量向另一个变量复制引用类型的值,复制其实是指针,因此两个变量始终指向同一个对象。
确定一个值是什么类型的变量可以使用typeof操作符,而确定一个值是那种引用类型可以使用instanceof操作符。
var s = “string”; alert(typeof s); alert(person instanceof object); alert(person instanceof Arrary); 是不是数组 alert(person instanceof RegExp);是不是正则等等
引用类型
object:
使用new Object();或者对象字面量表示法var obj = {} ;
Array:
检测数组可以使用if( Array.isArray(value)){ //对数组执行某些操作 }
数组的某些方法比如队列方法:pop(),push()....位置方法:splice()...位置方法:indexOf()...迭代方法:every(),some(),filter(),map()...缩小方法:reduce()和reduceRight()这些可以在手册里边查询
Date:
有getTime()....getFullYear()..等等函数提供使用,在手册里边查询
RegExp:
var exp = /pattern/flag 其中flag 有3个 g:用于所有字符串,而非在发现第一个匹配项时立即停止,i:表示不区分大小写,m:多行模式,即在到达一行文本末尾时还会继续查找下一行是否存在与模式匹配的项
使用test方法查看字符串是否符合正则
正则对象的主要方法是exec(),该方法是专门为捕获租而设计的。exec接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。返回的数组虽然是array的实例,但是包含两个额外的属性:index和input。
其中,index标识匹配项在字符串中的位置,而input表示应用正则表达式的字符串。在字符串中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)
var text = "mom and dad and baby"; var pattern = /mom( and dad( and baby)?)?/gi; var matches = pattern.exec(text); matches.index //0 matches.input //"mom and dad and baby" matches[0] //"mom and dad and baby" matches[1] //"and dad and baby" matches[2] //" and baby"
Function:
在ECMAScript中,最有意思的莫过于函数,函数实际上是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
function sum(a,b){ return a+b; } 这与下面使用函数表达式定义的函数的方式几乎相差无几、 var sum = function(a,b){ return a+b; };
其中解析器在向执行环境中加载数据的时候,对上边两种并非一视同仁的,解析器会率先读取函数声明,并在执行任何代码之前可用(可以访问),下边的函数表达式,则必须等到解析器执行到它代码所在的行的时候,才会真的被解释 执行。
函数没有重载这个说法,只会覆盖
在函数的内部,有两个特殊的对象,arguments和this。
每个函数都包含两个属性length和prototype。其中length标识函数接收参数的个数,对于ECMAscript中的引用类型而言,prototype是保存它们所有实例方法的真正所正在。prototype的属性是不可枚举的,因此使用for-in无法实现
每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。首先,apply方法接收两个参数:一个是在其中运行的函数的作用域,另一个是参数数组。其中第二个参数
可以是Array的实例,也可以是arguments对象。例如:
基本包装类型:
未来便于操作基本类型,ECMAScript提供了3个特殊的引用类型:Boolean、Number和String。
每个基本包装类型都有一些操作方法,String最多,search(),replace....等等。这些在手册里边都有,具体用到哪些可以自己查询,不过最好要有印象
单体内置对象:
Global、Math对象
Math保存数学公式和信息提供的一个公共位置,比如:Math.PI 这事π的值(3.1415926)
min()和max() Math.ciel() 向上舍入 Math.floor() 向下舍入 Math.round() 执行标准舍入
其中Global对象可以说是ECMscript中最特别的一个对象,因为不管你从什么角度上看,这个对象都是不存在的的,ECMScript中的Global对象在某种意义上作为一个终极的“兜底对象”来定义的。换句话说,不属于任何其他对象的属性和方法,最终都是它的属性和方法。事实上,没有全局变量和全局函数;所有在全局作用域中定义的属性和函数,都是Global对象的属性。比如:isNaN()、isFinite()、parseInt() 、实际上都是Global对象的方法。除了这些,Global还有一些其他的方法
URL编码方法:
encodeURI()和encodeURIComponent()方法可以URI(Uniform Resource Identifiers 通用资源标识符)进行编码,以便发送给liulanqi。
decodeURI() decodeURIComponent 对应解析上边的编码
eval()这个方法大概是整个ECMScript语言中最强大的一个方法;eval()方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript或者JavaScript字符串
下图为Global对象的属性
以上是关于学习Javascript的一些记忆东西的主要内容,如果未能解决你的问题,请参考以下文章
译文:18个实用的JavaScript代码片段,助你快速处理日常编程任务