javascript 学习(3)
1.关于object对象长度
若用.length测不出其具体长度,返回值为undefined;可通过for..in来计算出其长度;例:
1 var ob={a:"test1",b:"test2"}; 2 var size = 0; 3 delete ob.a; 4 for(var i in ob){ 5 alert(ob[i]); 6 size++; 7 } 8 console.info(ob.length);//undefined 9 console.info(size);//2
如果finally块使用return,continue,break语句使得解析语句跳出try,不管是否继续,编译器都会将其忽略。
3.with语句
作用是将object添加到作用域链的头部,然后执行指令,最后把作用域恢复到原始状态。不建议使用,原因:难优化,运行速度比普通代码慢
对象
1.除了字符串,数字,true,false,null和undefined之外,javascript中的值都是对象。
对象常见用法:创建、设置、查找、删除、检测、枚举它的属性。但是同一对象中不能出现同名属性。
2.具有三个对象和两个属性(三个对象:内置对象,宿主对象,自定义对象;属性:自有属性,继承属性)
3.原型
所有通过对象直接创建的对象都有同一个原型对象,并可以通过javascript代码Object.prototype获得原型对象的引用。通过关键字new和构造函数调用创建的对象的原型就是构造函数prototype的属性的值。没有原型的对象不多如Object.prototype就是其中之一。
4.object.create()
是一个静态函数,不提供调用方法。有两个参数。可以通过传入null来构建一个没有原型的新对象。他不会继承任何东西,包括toString()所以不能和“+”运算符一起正常工作。
5.对于一个对象的属性名是保留字或关键字必须使用[]来访问,例:o.["for"];当使用方括号时,我们说方括号内的表达式必须返回字符串。更严格的讲,表达式必须返回字符串或返回一个可以转换成字符串的值。
6.继承:如果o中的属性p是继承的,则他为只读。
7.删除属性:delete只能删除自有属性,不能删除继承属性(要删除继承属性必须定义这个属性的原型上进行删除它,而且这个影响到所有继承自这个原型的对象)。如果delete后不是一个属性值也会返回true。但是delete删除那些可配置性为false的属性(尽管可以删除不可扩展对象的可配置属性),某些内置对象的属性是不可配置的如通过变量声明的和函数声明的创建的全局对象的属性,在严格模式下,删一些不可配置属性会报一个雷型错误。
8.检测属性:in,hasOwnPreperty(),propertyIsEnumerale()
in运算符的左侧是属性名(字符串),右侧是对象。如果自有属性包括或继承属性中包括这个属性则返回true。
hasOwnPreperty()检测对象是否是自有属性。
propertyIsEnumerale()检测对象自有属性是否是可枚举属性。
9.枚举属性:
在ECMAScript 5定义三个用枚举属性名称的函数 :for...in,Object.keys(),Object.getOwnPropertyNames();
Object.keys():返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。
Object.getOwnPropertyNames():返回对象所有自有属性的名称,而不仅仅是可枚举的属性。
10.属性getter和setter(存取属性) 存取属性不具有可写性
如果它只有setter方法,那么它只有一个写属性
11.其他
Object.getOwnPropertyDescriptor(),获取对象中x属性的属性描述,代码及结果如下:
1 Object.getOwnPropertyDescriptor({x:1,y:2},"x") 2 //结果为 Object {value: 1, writable: true, enumerable: true, configurable: true}
若要设置属性的特性,或想要新建属性的某种特质则需要调用Object.defineProperty(对象,对象属性,需要修改的值)
1 var o = {}; 2 Object.defineProperty(o,"x",{value:"hahah",writable:false,enumerable:true, configurable:true}); 3 o.x = "jkjskdjksjd"; 4 console.info(Object.getOwnPropertyDescriptor(o,"x")); 5 //结果Object {value: "hahah", writable: false, enumerable: true, configurable: true}
12.对象的三个属性:原型(prototype),类(class),可扩展性(extensible attribute).
原型(prototype):通过new表达式创建的对象包含一个名为constructor的属性,这个属性指代创建个对象的构造函数。
13.对象序列化
可通过JOSN.stringify()和JSON.parse()来序列化对象和还原对象。
注:日期对象序列化结果是ISO格式的日期字符串,但JSON.parse()依然保存他们字符串形式,而不会将它还原成原始日期对象。
函数,RegExp,Error对象和undefined值不能序列化和还原
JOSN.stringify()只能还原枚举属性对象。
14.对象方法
在Array类的toLocalString()和toString()很像,唯一不同的是每个数组元素会调用toLocalString()方法来转换字符串
valueOf()要在将对象转换成某种原始值而非字符串时才调用,尤其是转换数字的时候。如果在需要使用原始值的上下文使用了对象,javascript就会自动调用这个方法。
toString()返回一个表示调用这个方法的对象值得字符串。
数组
1.数组中的值可以是常量,表达式,对象直接量或其他数组直接量例:
1 var a="this is a test"; 2 var arr = [1,"a",a,{f1:"hahah",f2:2},[1,2,3]];
2.如果省略组数直接量中的某个值,省略的元素将被赋予undefined值。
3.可以使用负数或非整数来索引数组,这种情况下数值会转换成字符串,字符串作为属性来用,只能当做对象属性。
4.稀疏数组:包含从0开始的不连续索引的数组。稀疏数组中,元素的length大于元素个数。
5.向数组中添加和删除元素
push()在数组尾端添加一个或多个元素。
unshift() 在数组首部插入一个元素,并且将其他元素已到更高的索引
delete a[i]删除数组元素与为其赋值undefined值时类似的,但是不会修改数组的length属性,也不会将元素从高索引处移下来填充删除属性的留白,如果从一个数组中删除一个元素,则这个数组变成了稀疏数组。
6.数组方法
array.join()将数组中的所有元素都转化为字符串并连接起来,最后返回一个字符串。默认是用逗号连接。
array.reverse()将数组中元素顺序进行颠倒。返回逆序数组。
array.sort()将数组排序后返回,不带参数时为升序排列。是按ascii码进行排序的。
array.concat()创建并返回一个新数组。
array.slice()方法返回指定数组的一个片段或子数组。它的两个参数分别指定了片段的开始和结束的位置。返回的数组将包含从开始位置到数组结束位置之间的所有数组元素。如果只出现一个参数,返回的数组将包含从开始位置到数组结束位子之间所有元素。如果指定一个参数,返回的数组将包含从开始位置到数组结尾的所有元素。如果出现负数,他表示相对于最后一个元素位置。
array.splice()前两个参数指定了需要删除的数组元素。紧随其后的任意参数指定了需要插入到数组中的元素。从第一个参数指定的地方开始插入。
array.pop()和array.push()数组实现先进后出的栈。
array.shift()和array.unshift() 后进后出。
array.toString()和array.toLocalString()
array.forEach() 重头到尾遍历数组,为每个元素调用指定函数。forEach()有三个参数:数组元素,元素的索引,元素本身。forEach()不能用break终止,若要终止函数将条件放入try..cach中并且能抛出异常,如果foreach调用foreach.break异常,循环会提前终止。在空数组调用上every()返回true,some()返回false。
array.map() 将调用的数组的每个元素传递给指定函数,并返回一个数组,他包含该数组的返回值,返回的是个新数组。如果是稀疏数组,相同的地方返回稀疏数组。长度相同,缺失元素相同。
array.filter()返回的数组元素是调用的数组的子集。它会跳过稀疏数组,返回数组总是稠密的。
1 var data = [1,2,3,,4,5]; 2 var sum = 0; 3 data.forEach(function(value){ 4 sum +=value; 5 }); 6 console.info(sum); //15 7 var data2 = data.map(function(x){return x*x}); // [1, 4, 9, 0, 16, 25] 8 console.info(data2); 9 var filter1 = data.filter(function(x){return x < data.length}); 10 console.info(filter1); //[1, 2, 3, null, 4, 5]
array.some()和array.every() 数组的逻辑判定:它们对数组元素应用指定的函数进行判定,返回true或false。 array.some()规则和“或”相似,array.every()规则和“与”相似。
array.reduce()和array.reduceRight() 使用指定的函数对数组进行组合,生成单个值。第一个是执行化简操作的函数。第二个(可选)的参数是一个传递给函数的初始值。
array.indexOf()和array.lastIndexOf() 若没搜索到,返回-1,有两个参数,第一个是索引值,第二个是起始值。
7.类数组对象
把拥有一个数值length属性和对应负整数属性的对象看做一种类型的数组。
8.作为数组的字符串
字符串的行为类似于只读的数组,除了用charAt()方法访问单个字符外还可以使用方括号。
函数
1.return语句终止函数执行,并返回表达式的值。若return中没有一个相关的值,则返回undefined。如果函数中没有return语句,则函数语句依次执行,最后返回undefined。
2.函数声明语句的话,函数名称和函数体均提前:脚本中的所有函数和函数中所有嵌套的函数都会在当前上下文其他代码之前声明。同时函数声明语句创建的变量是无法删除的。不能出现在循环或判断语句里。
3.任何函数只要作为方法调用实际上都会传入一个隐式的实参——这个实参是一个对象,方法调用的母体就是这个对象。
4.关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。如果嵌套函数作为方法调用,其this的值不是全局对象就是undefined。很多人误认为调用嵌套函数的this会调用外层函数的上下文。如果你要访问外部函数的this值,需要将this值保存在一个变量中。这个变量和内部函数都同在一个作用域内。
1 var test = { 2 m:function(){ 3 var self = this; 4 f(); 5 function f(){ 6 console.info(self === test);//true 7 console.info(this === test);//false 8 } 9 } 10 } 11 test.m();
5.argument[]适用于包含固定个数的命名和必须参数,以及随后个数不定的可选参数。argument不是真正的数组,而是一个实参对象。
3.嵌套函数
变量作用域规则:它们可以访问嵌套它们(或多重嵌套)的函数的参数或变量
4.callee和caller属性
在非严格模式下,ECMAScript标准规范规定callee属性指代当前正在执行的函数。caller是非标准的,但大多数浏览器都实现了这个属性,它指代当前正在执行的函数。通过caller属性可以访问调用栈。callee属性在某些时候会非常有用,比如在匿名函数中通过callee递归调用自身函数。
5.作为命名空间的函数
函数中声明的 变量在函数体内可见,在函数外部不可见。在javascript中无法声明只在一个代码块内可见的变量,于是,我们常常简单的定义一个函数用做临时命名空间。这个命名空间内定义的变量不会污染全局命名空间。
6.闭包
他们是对象,都关系作用域。作用域链在调用函数时的作用依然有用
1 var test_1 = "this is a test1"; 2 function test_2(){ 3 var test_1 = "this is a test2"; 4 function test_3(){ 5 var test_1 = "this is a test3"; 6 return test_1; 7 } 8 return test_3; 9 } 10 console.info(test_2()()
闭包具有自己所绑定的arguments,因此,闭包无法直接访问外部函数的参数数组,除非外部函数将参数数组保存在另一变量中。
7.函数属性,方法和构造函数
length属性 表示的是当前函数形参的个数,和arguments不同,arguments表示的是该函数实参的一个数组。
call()和apply()方法:①在严格模式下:call()和apply()第一个参数都会变成this的值,apply()和传入的实参都是放在一个数组当中。
bind()这个方法的主要作用是把函数绑定到某个对象上。
Function()构造函数