js高级程序设计(第三版)学习笔记(第一版)

时间:2021-03-31 03:18:27

ecma:欧洲计算机制造商协会
iso/iec:国际标准化和国际电工委员会


dom级别(10*)文档对象模型
1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)
2:对鼠标,事件,范围,遍历,还有对css样式表的支持
dom2:新接口...视图,事件(鼠标,移动),样式(css),遍历与范围(对文档树的操作)
3:对文档加载和保存,验证模块,对核心进行扩展,对xml.0规范
其他dom
svg可伸缩矢量图
mathml数学标记语言
mghi同步多媒体集成语言
ie5 dom1
mozilla 0.6.0 支持dom
firefox3完全支持dom1 dom2 dom3(部分)

bom(6*)浏览器对象模型
弹出新窗口
移动,绽放,关闭浏览器窗口
提供浏览器详细信息location对象
提供用户显示器分辨率screen对象

html中使用js方式
<script></script>在html内部使用
<script src='js.js'></script>外部使用
属性:async:用于下载此脚本 ,只对外部js文件有效
charset:字符集(一般情况下,设置成utf-8即可)
defer延迟执行脚本,在ie7版本之前有效(对外部js文件有作用)
language:不在使用
type:脚本文件内容,js在服务器端时,使用的是mime:application/x-javasciprt
src:外部文件路径
alert(obj)打印obj字符串内容
console.log(obj)向控制台输出obj字符串内容
现在的web应用程序都将js文件放在body层里面使用,这样做的好处是:当js代码被下载时,它会和body
里面的内容同时显示出来,如果js文件存放在head里面时,它会被下载,解析,和执行完成之后,才呈
现body主体内容,这样会在中间出现延迟时间,会造成页面的部分空白.
h5规范了对脚本按照它们出现的先后顺序进行执行
ie4到ie7对defer这个属性是支持的,ie8之后,就完全按照h5规则来制定
ie4,firefox3.5 safari5 chrome都最先支持defer属性
xhtml要设置成defer='defer'
async(异步脚本)与defer类似,但它不保证脚本的执行顺序
xhtml要设置成async='async'


js基础
1:区分大小写
2:不能以数字开头,第一个字符必须以字母或下划线或者$开头,后面跟着字母或下划线或者$或者数字
,采用驼峰大小写方式(第一个字母小写,其余每个单词贩首字母大写)
3:不能使用关键字,如functinon ,class,if等

//单行注释
/* */多行注释


在js中基于对象
严格模式
'use strict'支持(ie10+,firefor4+,safari5.1+,opera12+,chrome)
每个语句结束后,使用分号(;)来结束;

变量
var obj;这个是声明,但没有初始化值,如果当打印obj这个只声明的变量时,会显示undefined(未定义
);
obj=[];表示把右边的数据传给左边obj这个变量,让这个obj变量在内存地址中生成一个唯一的id地址
变量:它是一种用于保存js任何您需要的数据类型(如整形,数组),且是动态的,当这个变量obj改变
了它的数据类型时,内存中的(唯一id)地址,也跟着改变

如果在function中使用var 来声明变量时,那么这个变量将是局部变量,如果function功能结束后,那么
在function中所有的(比如局部变量)将被gc(回收机制),如果在function中没有使用var来声明变量时
,这个变量将是全局变量
var多行定义:var f1=1,f2=2,f3=[];
注意:在严格模式下:不能使用eval或者arguments这类变量
数据类型:
undefined null boolean number string (特殊的数据类型:object)
typeof:检测给定的变量是什么数据类型(它是一个操作符,并非函数),如下
基本语法:typeof obj;
typeof会返回以下几种情况
undefined:未定义
boolean:布尔值
string:字符串
number:数值
object:对象或null
function:函数

undefined:使用var声明时,但未初始化时,那么就是undefined

var a=1,b=2,c=[];
a,b,c=b,a+b,c交换
判断类型:typeof obj ,obj instanceof objx(推荐使用它)

null空指针对象:(返回object对象)对于保存对象的变量还没有变成真正变量时,使用null,程序员给定
的,使用null可以明白相应的变量是否已经保存了一个对象的引用
undefined的值它是派生于null值的
undefined与null之间是相等操作符(true),主要目的是:转换其操作数
undefined对于一个变量没有需要显示的时候,还有,没有初始化obj的时候,计算机给的

boolean:true(不一定1),false(不一定0)
var t1=true;
var f1=false;
使用Boolean(obj)函数可以将obj强制转换为一个布尔值,返回的结果是true或者false;

Number:数值
整型:
十进制:var intNum=55;
八进制:070;(严格模式下,如果使用八进制将出现错误)
十六进制:0x25;

浮点:(是根据计算机精度来决定的),最高精度是17位小数,但在进行计算算术时会出现精度问题
0.1+0.2等于0.30000000000000004这样的方式

var floatNum=1.23;

number的最小范围:Number.MIN_VALUE(5e-324)
最大范围:Number.MAX_VALUE(1.7976931348623157e+308)
如果不在上面(最大和最小值范围)将自动转换为特殊的+-Infinity(无穷)值,它是一个无法进行计算的
特殊数据结构;
isFinite()函数,用于判断这个参数是否在最小与最大值之间,如果是true,否则是flase

如下
a=Number.MAX_VALUE+Number.MIN_VALUE
alert
(isFinite(a))

Number.NEGATIVE_INFINITY Number.POSITIVE.INFINITY也可以得到+-Infinity的值;


NaN:表示一个本来要返回数值操作符未返回数据的值(不会出现错误),在js中什么数除了0,均是NaN
特点:任何数与NaN进行计算(包括NaN)返回NaN
NaN不等于任何数据(包括NaN本身)
isNaN()函数,可以接受一个参数,用于判断是否不是数值,当isNaN()接受到一个值之后,会尝试将这
个值转换为数据,如果这个参数是非数值时,返回结果是true,如下
isNaN('')
isNaN()也适用于对象,如果调用isNaN()函数时,首先会调用对象的valueOf()对象,然后确定譔对象返
回的值是否可以转换为数值,如果不能,则这个返回值再调用toString()方法,再测试返回值


数值转换
Number()用于任何数据类型
规则:如果是布尔值,转换为0和1
如果是数字,则传入和返回
如果是null,返回0
如果是undefined,返回NaN
如果是字符串
如果字符串中只包含数字的(包括前面带正号或者负号情况),将转换为十进制,如
'1'会变成1,'011'会变成11(忽略11前面的0)
如果字符串中包含有效浮点格式,转换对应的浮点格式(规则与转换为数值类似)
如果字符串包含有效的十六进制格式,转换为大小相同的十进制整数
如果字符串为空,转换为0
如果字符串除上述条件之外的字符,均转为NaN
如果是对象,调用对象的valueOf()方法,然后按照上面的规则进行处理,如果返回是NaN,再调用对象
toString()方法,然后再次使用上面的方法进行处理,如下


parseInt()转换字符串,处理整数,如果第一个是数值字符或者负号,,它将继续解析下一个字符,直
到遇到非数字字符或者负号,如果遇到非数字或者非负号时,返回NaN
parseInt()支持八进制,十六进制,十进制等
parseInt('0x')返回
NaN,如果0x之后没有数值或者不是数值时
parseInt()第二个参数(指定几进制)
parseFloat()用法与parseInt()一样,但区别是:可以用于整型和浮点,如果遇到第一个小数点时是有
效的,当再次遇到第二个小数点时无效,如
22.35.4,会返回22.35

string:字符串,是不可变的,如果想改变这个字符串变量,那么必须先销毁这个字符串变量,然后重新
定义
在字符串,使用+:它是拼接
转换为字符串:str.toString(),默认情况下,不需要在toString()中使用参数,默认十进制方式返回数
值字符串,可以输出以十进制,二进制等相关几进制;

如果不清楚值是否是null或者undefined时,可以使用String()转换函数
String()转换规则
如果值有toString()时,则调用此方法(无参数)返回相应结果
如果是null,返回'null'
如果是undefined,返回'undefined'

null与undefined没有toString()方法


Object对象,使用object对象可以给实例对象添加属性和(或者)方法,也可以自定义对象
var o=new Object();

Object每个实例都具有以下属性和方法
constructor:保存创建当前对象函数:构造函数,就是Object()
hasOwnProperty(propertyName):用于检查给定属性在当前对象实例中(并非实例原型中)是否存在,
propertyName必须以字符串方式指定
isPrototypeOf(object):判断传入的对象是否是传入对象的原型
propertyIsEnumerable(propertyName):判断给定的属性是否能够使用for-in进行枚举,propertyName必
须以字符串方式指定

toString()返回对象字符串表示
valueOf()返回对象字符串,数值或者布尔表示,与toString()方法一样
toLocaleString():返回字符串表示,该字符串与执行环境地区对应
操作符
一元操作符
i++:先在i使用当前值,然后再加1
++i:先计算,后使用这个新值

++,--用于的规则可以在数值,字符串,布尔,浮点,对象等
如果是一个有效的数字字符串,转换为数值,然后回加减1,字符串变量变成数值变量
如果不是一个有效的数字字符串,将变量设为NaN,字符串变量变成数值变量
用于布尔时,将转换成0或者1再执行加减1,布尔值变量变成数值变量
浮点数值时,执行加减1操作
如果是对象的话,调用对象的valueOf()方法,然后按照上面的规则进行处理,如果返回是NaN,再调用对
象toString()方法,然后再次使用上面的方法进行处理
var o={
valueOf:function()
{


return -1;

}

 

};

一元加入只剩符:(+,-,*,/)等
obj=+obj,如果+/-放在obj前面,不会对+/-obj数值造成任何影响

位操作符(整形){暂时不讨论这部分}


布尔操作符
not(非) and(与) or(或)

not(!)
规则
以下情况如果使用not条件式,均返回false
如果是对象/非字符/非0数值
除以上情况均是true

js中可以使用奇数!表示为 not 偶数!表示取反

and(&&):表达式1与表达式2同时为true时才能为true

第一个是对象,返回第二个条件
有一个是null,则返回null
有一个是nan则返回nan
有一个是undefined,则返回undefined


or(||)
条件表达式中,其中某个为true,则为true

如果第一个是对象,则返回第一个
如果第一个条件为false,则返回第二个
如果2个都是对象,则返回第一个
如果2个都是null/nan/undefined,返回null/nan/undefined;

乘法:*
规则;
如果是数值,则执行常规计算,无论是2个正数还是2个负数计算结果都是正数,如果其中一个是有符号
的,那么返回的结果是负数,如果相乘之和超出范围时,则返回Infinity或-Infinity
如果其中一个是nan,则返回nan
如果infinity与0相乘,则返回nan
如果infinity与非0数值相乘,返回+/infinity
如果infinity相乘,则返回infinity
如果其中某个并非数值,那么将会在后台调用Number()将转换成数值,然后根据上面的规则进行计算

除法(/)
它的规则与乘法类似
如果是数值,则执行常规计算,无论是2个正数还是2个负数计算结果都是正数,如果其中一个是有符号
的,那么返回的结果是负数,如果相乘之和超出范围时,则返回Infinity或-Infinity
如果其中一个是nan,则返回nan
添加几条不同的
0除以0,返回nan
非0除了0,返回+-infinity
如果infinity相除,则返回nan;
如果infinity被任何非0数值除,返回+-infinity
如果其中某个并非数值,那么将会在后台调用Number()将转换成数值,然后根据上面的规则进行计算

求模(%)
它的规则与乘法类似
如果是数值,则执行常规计算
如果其中一个是nan,则返回nan
如果被除数是无穷大值而除数是有限大的数值,返回nan
如果被除数是有限大而除数是0,返回nan
如果infinity相除,返回nan
如果被除数是有限大的数值,而除数是无穷大的数值,则结果是被除数
如果被除数是0,返回是0
如果其中某个并非数值,那么将会在后台调用Number()将转换成数值,然后根据上面的规则进行计算

加号(+)
不是字符串时
如果相加的并非是字符串,那么进行常规计算
如果+/-infinity之间计算,则返回+/-infinity
如果infinity与-infinty进行计算,返回nan
如果+/-0之间的计算,那么是常规计算
除-0+-0等于-0外

如果是字符串(+),那么进行拼接
如果只有一个操作符是字符串,那么将另一个转换为字符串,然后再拼接
如果操作符是一个对象,数值,或者布尔,那么调用它们的toString()方法取得对应的字符串值,然后
根据上面的规则,对于null和undefined分别调用String()函数并取得字符串'null'和'undefined'


减法(-)

规则:
如果均是数值,进行常规计算
如果某个是nan,返回nan
infinity与infinity计算,返回nan
-infinity与-infinity计算,返回nan
infinity与infinit-y计算,返回infinity
-infinity与infinity计算,返回-infinity
如果其中一个是字符串,布尔值,null或者undefined先从后台调用Number()函数转换为数值,然后根据
减法规则,如果转换结果是nan的话,那么结果就是nan;
调用对象的valueOf()方法时,如果得到的结果是nan,那么返回nan,如果没有valueOf()方法,则调用
toString()方法,然后将字符串转换为数值;


关系操作符
<,>,>=,<=,!=,==
规则:
如果比较的是数值,那么就执行数值比较
如果是字符串比较,那么取得对应字符串的编码
如果其中一个是数值,那么另一个将转换为数值,然后再进行比较
如果其中一个是对象,那么先调用对象的valueOf()方法时,然后使用上面的规则,如果没有valueOf()方
法,如果对象没有valueOf()方法,则调用toString()方法,并根据上面的结果进行执行比较

如果其中一个是布尔,那么先转换成数值,然后再比较

如果其中某个与nan比较,永远返回false
当字符串与数值比较时,永远都返回false,因为字符串被转换成nan了
总结:任何操作数与nan进行比较时,永远都是false;


相等操作符(==与!=):先转换再比较,全等与不全等--仅比较而不转换
规则
如果其中一个是布尔,在比较相等之前先将其转换为数值--false(0)而true(1)
如果一个是数值,另一个是字符串,那么先将字符串转换为数值,然后再比较
如果一个是对象,另一个不是,那么调用对象valueOf()方法,然后按照上面规则进行比较

如果2个操作符在进行比较时,使用以下规则
null与undefined是相等的
要比较相等之前,。不要将null与undefined转换成其他任何值
如果其中一个是nan,那么返回结果是false,而不相等返回true
nan之间比较,永远为false,,也就是nan不等于 nan
特殊值
true==2;false
undefined==0;false
null==0;false
'5'==5;true

str.toLowerCase()小写
str.toUpperCase()大写


全等(===)不在转换,仅比较,如果结果为false时,因为对应的数据类型不同
条件表达式
三元操作符exr0 ?exr1:exr2

赋值操作符:将右边的值赋给左边变量
+=,-=,*=,/=
<<=左移 >>=右移
>>>=无符号右移
多行语句
var a=1,b=2,c=2;
var num=(1,2,3,4,5);结果num是5,会取得num的最后一个值


语句体
if语句
语法
if(表达式1){

语句体1
if(表达式_0){


}else{
语句体
}
}else if(表达式2){

语句体1
}else{

语句体3
}
如果if条件表达式为true时,执行if语句下面的语句体,else if else相关语句不再执行
如果if条件表达式为flase时,执行else if(如果多个时,根据情况为true时,执行) else不在执行
如果上面的条件均不满足时,执行else语句

do-while后测试循环语句,即只有在循环体中代码执行后,才测试出口条件(至少会执行一次代码请求)
语法
do{

语句体
}
while(表达式);

while语句(一般情况,如果是没有顺序,使用它)
语法
while(表达式){

语句体
}


for循环
语法:
for(表达式1,表达式2,表达式3){

语句体

for循环与while循环其中就是一样的
在for循环中,变量初始化表达式中,可以不使用var关键字,可以在外部生成 这个变量,因为外部变量
可以在for循环中访问到
var count=0,i=1;
for(i;count;i++){

}
死循环
for(;;){

}
while(true){


}

for-in迭代语句体(和python中的类似:枚举)
语法
for(迭代别名 in 表达式){

语句体

}
在使用for-in之前,会检测对象的值是否存在null或undefined


}

(1*)label语句
语法
label:表达式;,常用for等循环一起使用
作用:是在代码中添加标签,以方便未来使用

break(跳出循环,不在执行)和continue(跳出本次循环,然后从循环顶部继续执行)与label语句联合使

且在break/continue后面可以添加一个变量,如下
label:for(){
break label

}

with语句
语法:
with(表达式){

语句体
}
作用:将代码的作用域设置到一个特定的对象中,主要是为了简化多次编写同一个对象时
缺点时,使用with会让性能下降,在开发中,不建议使用

(10*)switch语句
语法
switch(表达式){
case v1:表达式
break
....
case vn:表达式n
break
default:
表达式
}
它的语法与if语句类似
注意:在case中省略break时,将会继续执行下一个case语句中的代码
default用于在表达式中不匹配前面所有case语句中
如果在case中省略了break,建议在case下面使用注释来说明情况
这边的v1不仅仅只能表示数值,也可以表示其他数据类型,如对象等


函数
语法
function funcname(形参){
函数主体

}funcname(实参)

形参也是局部变量
function funcname(形参<传值>){

var funcname;局部变量
}

funcname(实参 传值) 实参是全局变量


在js中,function中括号里面的参数,无论给多或者不给,js永远不会报错,也不会关心传入的参数是
什么类型,因为在js内部机制中使用一个数组来表示,,即使这个参数为0或者更多,js也没有什么错误
提示
数组的长度:array.length

arguments.lenght可以获取函数名中传递给函数多少个参数
arguments[int]它还可以和参数一起使用

arguments它的值永远与对应命名参数的值保持同步

 

2016-4-10 19:54分的

变量、作用域和内存问题
js中变量是动态的弱类型,并不会确定会保存什么类型的数据结构,
变量的值在一定周期内会修改其中的值

基本类型与引用类型之间的区别
基本类型:number,string,null,undefined,boolean ;而这些是直
接能够保存值给变量的
引用类型:不能直接保存在变量中的,只能从内存地址中查找到对应
的id


动态属性
基本和引用类型创建方式很类似:创建一个变量并为此变量赋值,然
后可以(增,删,改,查)属性和方法

//使用Object()方式创建一个新对象
增加
var person=new Object();
person.name='python';
person.age='25';
person.sex='man';
alert(person.name+person.age+person.sex);
如果您创建的属性没有被销毁,那么这个属性将永远存在
当访问一个没有给定的属性或者方法时(未创建时),js并不会报错,
返回一个undefined提示

复制变量值:从某个变量中复制出一个新的(并非是真正的<复制>)
,然后将这个复制的值传入给新的变量,然后在内存地址中创建一个
新变量的 唯一id号,这个规则与python中的潜copy类似;
看个例子
var null1=5;
var num2=null1;
null1中保存的是这个5,当使用null1的值来初始化num2时,它也保
存了5,但num2与null1中的这个值是独立的,
num2中的5只是null1一个潜copy,所以无论null1怎么操作,都不会
影响num2,怎么判断呢,通过查看对应变量的内存id地址


如何打印js中变量的内存地址?


如果变量是从引用类型复制出来,那么会复制出一份放到新变量中,
然后在内存地址中分配同一个的id地址,这个新复制的值其实类似c语
言中的指针,这个指针指向新变量堆中一个对象,那么这2个其实是
引用同一个对象,如果其中一个变量改变后,另一个也会跟着变化,
这个其实就类似python的深copy


var arr1=new Object();
var arr2=arr1;
arr1.name='python'
alert(arr1.name)
alert(arr2.name)
alert(arr1.name==arr2.name)

传递参数
在js中所有函数的参数都是<按值传递>的,就是把函数外的值复制给
函数内参数,就像把值从一个变量复制到另一个变量一样
,在向参数传递基本类型时,被传递的值会给函数中的局部变量,即
参数名,或者说是argumebts对象中的一个元素,这个传递给局部变
量的值会在内存地址中复制出一份,分配一个id号,因此局部变量的
变化会反映在函数外,如下
//基本类型
function add(num) {
num+=10;
return num
}
var count=20;
var result=add(count);
alert(count);//20局部变量
alert(result);//30全局变量
//如果num是按值传递时,那么count也会跟着变化,变成30

//按值传递
function setName(obj) {
obj.name='python'
}
var self=new Object();
setName(self);
alert(self.name);//python
//将Object创建一个对象,并保存在变量self中,然后这个
变量被传递给setName(),赋值给函数中
//obj这个参数,也就是说obj与self引用是同一个对象,也
就是说这个obj添加了attr时,函数外的那个变量
//也跟着变化,因为self指向内存中且只有一个对象,且它
是全局变量

//证明下上面代码的正确性
function setName1(obj) {//函数内的obj是一个局部变量
obj.name='PYTHON1111';
obj=new Object();
obj.name='c++'
}
var set1=new Object();
setName1(set1);
alert(set1.name)//PYTHON1111
/*setName1(obj) 中添加了2行代码,第二行中重新定义了
一个对象
* ,第三行是obj定义带有 不同的属性,当函数外的变量传
递给函数名时,那么这个attr
* 属性被设置为,obj.name,然后又将新对象赋给变量obj时
,obj下面的attr的值就会成c++
* 如果函数外部的变量按引用传递,那么变量就会自动修改
为c++,但是当再次访问函数外的变量.attr时,仍然显示obj.name的
值,而并非是c++值
* 即使在函数内部重写这个obj时,那么这个变量只是在函
数体内变化,并不会影响函数外的变量,当函数执行完之后,那么内
部的局部变量
* 将被销毁*/

 


//检测变量类型:1
var s='hello';
var b=true;
var i=22;
var u;
var n=null;
var o=new Object()
alert(typeof s)//string
alert(typeof b)//number
alert(typeof i)//number
alert(typeof u)//undefined;
alert(typeof n)//object
alert(typeof o)//object

//检测类型:2(推荐)
//基本语法:obj instanceof 表达式,其中obj必须是表达式
的实例,才能返回true,否则返回false,注意:基本类型不是对象

alert(121)
function d1() {
return
}
var d2=new d1()
var arr=new Array()
alert(d2 instanceof d1)
alert(arr instanceof Array)
typeof用于基本类型的判断
而instanceof用于引用类型的类似
执行环境与作用域
执行环境定义了变量或者函数有权利访问其他数据同,决定各自的行
为,都有一个与之关联的变量对象,所有变量和函数都保存在这个对
象中,然后我们程序员无法去访问和处理它,但js底层和js引擎会帮
助我们去后台处理它
全局执行环境:window,所有全局执行变量都是这个window对象的属性
的方法创建出来的,在某些情况下,所有代码执行完了之后,window
环境(中所有的,包括变量)将会销毁掉.
每一个函数体都有一个执行环境,当执行一个函数体,那么就会被推
入一个环境栈中,当函数执行后,此栈跳出环境
当代码在环境中执行时,会自动创建一个名为作用域的变量
作用域链:保证对执行环境有权访问所有变量和函数的有序访问,它
的前端,永远在当前执行代码所有的环境对象中,环境如果是函数时
,那么活动对象是变量对象,活动对象下一个变量对象来自(可能是
外部)对象,以此类推。。。全局执行的变量永远都是作用域链最后
一个对象
注意:活动对象一开始只包含一个变量,即arguments对象(它在全局
变量中是找不到的)
变量的搜索规则
先从函数的局部变量中开始搜索,如果找到这个变量,那么就使用它
,如果找不到这个局部变量,就到全局变量中查找,如果全局变量中
找不到,那么就报错
例子
var color='blue';//全局变量
function change() {
if(color=='blue'){
color='red'
}else{
color='blue'
}
}
change()
alert('颜色是'+color)
//另外在局部变量中定义的变量可以在局部环境中与全局变
量互换使用
var color='blue';
function chang1() {
var anotherColor='red';
function swapColor() {
var tempColor=anotherColor;
anotherColor=color;
color=tempColor;
//这边访问上面3个变量的值
}
//这边能访问全局变量和anotherColor,无法访问
swapColor中的tempColor
}
//这边只能访问全局变量,无法访问函数内的变量
chang1()

延长作用域链:在这经的前端临时增加一个变量对象,当函数执行完
之后,该变量对象被销毁
语法
try-catch语句的catch块:会创建一个新变量对象,其中包含被抛出
错误对象声明
with语句:会将指定的对象添加到作用域链中
例子
function url() {
var qs='?debug=true';
with (location){
var url1=href+qs;
}
console.log(url1)
}
url()

with语句接受了一个location对象,因此会包含所有location对象所
有的属性与方法,这个变量对象被添加到作用域链前端,url()函数
了一个局部变量qs,当with语句中的引用变量href(其实是
location.href),执行当前环境,当引用变量qs时,引用则是在url
()定义那个变量,qs位于函数环境对象;url1它成为执行环境一部分
,可以作为函数的return进行返回


无块级作用域
if(true){

var color='blue';
}
alert(color);//blue
//在js中if语句变量声明将会把变量添加到当前执行环境(
也就是全局环境)
//但在for循环中有差异,如下
for(var i=0;i<=10;i++){

alert(i)//1 到10
}
alert(i)//11
//对于块级作用域来说,for语句初始化变量的表达式所定
义的变量,只会在循环体之内,但在js中for循环即使执行完了,变
量依然会在循环体外存在
1:声明变量:使用var声明变量会自动被添加到最接近的环
境中,在函数内,也就是局部变量;在with语句中,最接近是函数环
境,如果初始化时没有var声明,那么它就是全局变量
function add(num1,num2) {
var sum=num1+num2;
return sum
}
var result=add(20,10);//30
alert(sum);//报错
//注意:在函数体内省略var来声明的话,那么这个变量就是全
局变量
function add(num1,num2) {
sum=num1+num2;
return sum
}
var result=add(20,10);//30
alert(sum);//30
2:查询标识符
在某个环境中为了读取或者写入而引入一个标识符,那么通
过搜索来确定该标识实际代表什么
,搜索过程从前端开始,向上逐级匹配,如果在局部中找到
,就搜索停止 ,变量就绪
,如果未在局部中找到,那么继续向上(全局)查找,如果
在全局中未找到,那么报错
var color='red';
function color1() {
return color
}
alert(color1())

var color='red';
function c1() {
var color='blue';
return color
}
alert(c1());//blue
注意:访问局部变量速度比访问全局速度快;
3:垃圾收集(gc):自动垃圾收集机制
js引擎会自动帮我们管理执行过程的使用内存
如:局部变量在函数执行过程后,局部变量就gc了
,这样局部变量会从内存地址中释放出来
垃圾收集器必须会跟踪哪个变量有用和没有,对于
不在使用的变量,打上标记,以方便回收

标记清除:当变量进入环境时(比如函数体内),它从逻
辑上来说:永远不会翻译进入环境变量所占用的内在,只执行进入相
应的环境,就可能使用到它们,当变量离开环境时,那么称为"离开
环境"
任何方式都可以标记变量,或者使用一个进入环境的变量列
表及一个离开环境的变量来跟踪哪个变量变化
gc会在运行时给存储在内在中变量加上标记(任何方式均可
),接着会去年在内存环境中所改变的变量进行一个标记,当这些变
量再次被加上标记时,那么被加上标记的变量js视为需要回收的变量
,原因是内存空间中无法再次使用这些被标记需要删除的变量,最后
gc完成对内存清除工作,销毁那些不在使用(带标记)的变量,现在
主流的浏览器均支持js gc回收垃圾机制

引用计数:也就是跟踪记录每个值被引用的次数。当声明了
一个变量并将一个引用类型赋值给变量时,那么这个引用次数为1,
如果同一个变量又赋值给另一个变量时,那么该引用次数+1,如果包
含对这个引用的变量取得另外一个企,那么这个引用-1,当引用次数
为0时。则再访问这些值,因为这些变量被gc了,内存中不存在这些
变量的id
循环引用:是指对象A中包含一个指向对象B的指针
,而对象B中也包含一个指向对象A的引用。
例子:
function problem() {
var objectA=new Object();
var objectB=new Object();
objectA.someOtherObject=objectB;
objectB.anotherObject=objectA;
}//objectA与objectB之间是相互引用的,也就是说,这2个
变量次数是2;,在采用清除标记的情况下,函数执行完结果之后,
这2个对象都离开
//但当函数执行完之后,objectA和objectB依然存在,因而
它们的引用次数永远不为0,如果这个函数多次重复调用,那么内存中
会存在大量的垃圾无法回收
//com:组件对象模型
//避免循环引用问题:使用var obj=null方式将其手工断开
原生js对象与dom元素间的连接
//如果设置为null时,当垃圾收集器下次运行时,就会删除
这些值gc它们在内存中的数据


性能问题
垃圾收集器它是周期性运行的,如果分配的内存数量OK的话,那么gc
工作量也是很大的
ie的gc根据内存进行分配处理的,以256个变量,4096对象或(数组
)字面量和数组元素或者64KB字符串,达到前面的任何一点临界点,
gc便运行,但当一个脚本 中含有很多变量时,这个脚本可能会在周
期内一直保存那么多变量会加重gc的工作和效率
在ie7发布后,js引擎的gc改变了工作方式:
以256个变量,4096对象或(数组)字面量和数组元素或者64KB字符
串,变成了动态的修正,如果gc回收率在内存中使用低于15%时,那
么以256个变量,4096对象或(数组)字面量和数组元素或者64KB字
符串,情况增加变成2倍;如果gc回收率在内存中使用达到85%时,那
些上面的情况就重置默认值
在ie中调用window.CollectGarbage()会立即调用gc
在如opera7及更高版本中,调用window.opera.collect()也调用gc
管理内存
在js中:分配给web浏览器内存低于分配给桌面应用程序;这样做出于
安全考虑,防止资源消耗来崩溃系统
限制内存不仅影响变量分配内存,还影响栈及线程的执行数量;
这样的情况下,只有优化内存占用是最佳方式,当某个变量不在使用
时,应该将设置为obj=null来释放引用(解除引用:适用于全局和局
部变量的属性),局部变量会在它们离开时执行环境中自动被解除引
用,如下
function chreate1(name) {
var locahose=new Object();
locahose.name=name;
return locahose
}
var globs=chreate1('Nicholas')
//手工解除globs的引用
globs=null;
/*解决一个值的引用并非是自动回收该值所占用的内存;解除引用的真正作用是让值脱离执行环境,以方便gc在理光运行时,进行回收*/


//基本类型和引用类型共同点
/*基本类型值在内在中固定大小空间,它只保存在栈内存中
从一个变量向另一个变量复制基本类型的值,只是这个值的潜复制
引用类型值是对象,保存在栈内存中
包含引用类型值的变量实际上包含并不是对象本身,而是该对象指针
一个变量如果使用引用类型,进行复制时,复制的是指针,那么这2个变量都指向同一个对象

* */

 

(10*)引用类型

引用类型的值(或者对象)是引用类型的一个实例,它是一种数据结构,用于将数据和功能组织到一起,也被称为<类>

 

对象是某个特定引用类型的实例,通过new方式,后面跟着一个构造函数来创建,构造函数本身就是一个函数,如下

Var person=new Object();

创建了一个名为Object()引用类型的一个新实例,将这个实例保存到变量person中,Object()定义了默认的属性和方法,还有其他的,如日期,时间,正则等

(10*)Objectjs它最常用,也是最基本的用于创建一些程序员需要的属性和方法的

创建object实例方法2

1:通过new操作符 后面跟着Object 构造函数方式,如下

var pesron=new Object();

pesron.name='python';

pesron.age=25;

2:通过对象字面量(或者叫键值对)方式创建,作用与1中的相同,但大量简化了编写步骤,如下(个人 我建议使用这种方式),因为json(网络上)也是使用这种方式,而在python中字典和json也是这样操作的

var pesron={

           name:'python',

           age:20,

           sex:''

 

       };

我写下它的基本语法

Var obj={key1:value1,key2:value2,.....};

但到最后一组键值对时,不用加逗号;

这边的key可以是整形,字符串,但是不能使用如数组(动态的数据结构)

3:通过{}来创建来创建一个对象,如下

var pesron={};

     pesron.name='python';

对象字面量语法:推荐只在考虑对象属性名的可读性使用

如果使用对象字面量定义对象时,实际上并不会调用Object()构造函数(firefox 2及更早版本会调用object构造函数,但在firefox 3之后不会出现这个问题)

 function display(args) {

         var output="";

         if(typeof args.name=='string'){

 

             output+="Name:"+args.name+'\n'

         }

         if(typeof args.age=='number'){

             output+='Age:'+args.age+'\n'

         }

         alert(output)

     }

        display({

            name:'Python',

            age:20

        });

        display({

 

            name:'c++'

        })

 

在这个display()函数中,使用了一个名为args的参数,这个参数可以是带有name或者age,也可以没有带属性,通过typeof方式来判断属性是否存在,然后根据相应的属性打印出对应的信息

 

如何访问对象字面量属性,2种方式

1:obj[‘obj1’]

2:obj.obj1

基本上这2种都是可以的,但区别在于[]可以通过变量来访问属性名

 

[]中的属性不使用引号或者没有这个属性时,js会返回undefined

一般情况 下,建议使用第1种情况,除非特殊情况下使用第2

 

 

 

 

(10*)Array数组:它是可以保存您需要的数据结构,且数组是动态的,可以动态的添加,删除,修改等操作

创建array方式

1:

Var arr=new Array()

2:预先定义一个指定数量的数组,那么这个数组的长度变成lenght属性的值,如下

Var arr=new Array(10);

3:创建一个非空的数组

 Var arr=new  Array(a,b,c);

4:创建指定的项

Var arr=new Array(3);

Var arr=new Array(a,b,c);

5:可以省略new来创建数组,与上面相同

Var s1=Array();

 

6:通过[]方式来创建

Var s=[];//

Var s=[1,2,3];//3

Var s=[1,2,]不建议这样操作,可能是包含2或者3

Var s=[,,,,]同上

在数组中,是通过[index]方式来获取数组对应的值的,如下

Var s=[1,2,3,4,5,6]

打印 S[0]

修改s[0]=’hello’

新增S[6]=’obj’

索引会自动增加的

 

获取数组的长度:arr.length

Arr.length中的length这个属性并非是只读的,它可以从数组末尾移除项或者添加新项,如

Var color=['red','blue','green']

 Colors.length=2;

Alert(color[2]);//undefined;

 

在数组的末尾添加需要的数据

Obj[obj.length]=obj1

数组的索引最后一项永远都是length-1,那么下一个新项就length,会自动更新索引中的变化信息

当给出的索引值超出当前数组大小时,会重新计算长度,即长度值等于最后一项索引+1,如下

 

Var color=['red','blue','green']

 Colors[99]=’break’

Alert(color[99]);//break

注意,从398之间的值实际上不存在 ,所以返回undefined;

数组最多可以包含4294967295项,当超出这个范围时,会出现异常

 

判断数组类型:使用instaceof

如下

If(value instanceof Array){
   语句体

}

Instanceof如果只执行一个全局环境,网页中包含多个框架,也就是说存在2个以上不同版本的array构造函数,如果从一个传入另一个框架的数组,那么传入的数组与在第二个框架中原生创建的数组分别是独立的构造函数

判断数组的方法:array.isArray(obj)是否是数组,不用管理是否是从全局执行环境中创建出来的

支持.isArray()浏览器:ie9,firefox4+,safari5+,opera 10.5+,chrome

转换方法

toLocaleString()把数组转换为字符串,并返回结果。创建一个数组会以逗号分隔的字符串

toString():返回由数组中每个值的字符串拼接而成一个以逗号分隔的字符串,把数组转换为字符串,并返回结果。

valueOf()返回的还是数组

例子

var colors=['red','blue']

colors.valueOf()//["red", "blue"]

colors.toString()//"red", "blue"

colors.ttoLocaleString()//"red", "blue"

 

var p1={

         toLocaleString:function () {

             return'python'

         },

         toString:function () {

             return'c++'

         }

 

     };

        var p2={

         toLocaleString:function () {

             return'java'

         },

         toString:function () {

             return'c'

         }

 

     }

        var p3=[p1,p2]

        alert(p3)//c++,c

        alert(p3.toString());//c++,c

        alert(p3.toLocaleString())//python,java

        //注意:如果想取某个其中每一项,调用toLocaleString(),而不toString()

 

Arr.join(obj)使用它可以使用不同的分隔符来构建这个字符串,只接受  一个参数,即用于分隔字符串,返回包含所有数组项的字符串,如下

如果不在join()中传入一个参数或者传入了undefined时,会使用逗号作为分隔符,在ie7及更早版本,如果使用undefined,会出现错误

如果在数组中使用(某一项)null或者undefined,那么使用join(),toSting(),toLocalseString(),valueOf()对应的那项返回的结果为空字符串

数组的栈方法(lifo)先入先出

Arr.push():将字符串推入数组末尾,并将返回的结果保存在变量中

Arr.pop():返回数组的最后一项

 

var colors=Array();

      var count=colors.push('red','green');//添加2

     //push()可以接受任意数量的参数,把它们逐个添加到数组末尾,并返回修改后的数组长度

        alert(count);//2

        count=colors.push('blue');//添加1

        alert(count);//3

        var item=colors.pop();

     //pop()将数组最后一项移除,减少数组的length值,返回移除的值

        alert(item)//推出blue

        alert(colors.length);//2

 

另一个例子,push()与其他数组连用,如下

 

 var col=['red','blue'];

        col.push('python');

        col[3]='c++'

        alert(col.length);//4

        var item=col.pop();

        alert(item)//c++

 

队列(lifo)后进先出

Shift()删除第一个元素并返回数组

var col=['python'];

        col.push('java');

        alert(col);//python,java

        col.push('c++');

        alert(col);//python,java,c++

        var item=col.shift();

        alert(item);//python

        alert(col.length)//2

Unshift()shift()功能刚刚相反:

Unshift():从数组末尾移除项

 var col=['python'];

        col.push('java');

        alert(col);//python,java

        col.push('c++');

        alert(col);//python,java,c++

        var item=col.unshift();//返回一个新数组的长度

        alert('数值是:'+(item));//数值是3

        alert(col.length)//2

重排序方法:reverse()反转和sort()

 

对象的本质

   var revesed=[1,3,4,5,6];

        alert(revesed.reverse());//6,5,4,3,1

在默认情况下sort()按升序排列数组项,最小的项在最前面,最大的项的在最后项,例子

var revesed=[1,3,4,5,6,-4,-7,-6,9];

alert(revesed.sort());//-4,-6,-7,1,3,4,5,6,9

sort()方法可以接受一个参数,用于比较函数作为参数

 

比如函数接收2个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果2个参数相等,返回0,如果第一个位于第二

 

个后,返回正数

例子:升序

 function max_min(v1,v2) {

            if(v1<v2){

                return -1

            }else if(v1>v2){

                return 1

            }else{

                return 0

            }

        }

 

 var v=[300,200,1,5,10,15];

        v.sort(max_min)//1,5,10,15,200,300

        alert(v)

 

例子:降序

  function max_min(v1,v2) {

            if(v1>v2){

                return -1

            }else if(v1<v2){

                return 1

            }else{

                return 0

            }

        }

        var v=[300,200,1,5,10,15];

        v.sort(max_min);//300,200,1,5,10,15

        alert(v)

注意:如果反转的情况下,建议使用revese()速度高于sort()

revese()sort()方法返回的值是经过排序之后的数组

 

 

对于数值或者其他的valueOf()方法返回数值对象类型,使用如下方式

function num(s1,s2){

return s2-s1

}

 

操作方法(一般5*)

concat()方法可以基于当前数组中所有项创建一个新数组,也就是说:这个方法会创建一个当前数组的副本,然后接受参数添加

 

到这个副本的末尾,最后构建一个新数组,在没有给定concat()参数时,它只复制当前数组并返回副本,如果传递了参数给

 

concat方法一个或者多个时,那么该方法会把这些数组添加到结果数组中,如果传递的不是数组,那么只是简单的把结果添加

 

数组末尾,如下

var col1=['red','green','blue'];

        var col2=col1.concat('yellow',['black','browm']);

        alert(col1);//'red','green','blue'

        alert(col2)//'red','green','blue','yellow','black','browm'

slice()基于当前数组一个或者多个项创建一个新数组,可以接收1个或者2个参数,即开始和结束位置,如果只给定一个参数时

 

,那么在指定位置开始到当前数组的末尾所有项,如果给定的是2个参数,那么就从指定的开始与结束之间的项(不包括结束位

 

置的项),注意:它是不会影原数组的变化,如下

 var col1=['red','green','blue','yellow','black','browm'];

        var col2=col1.slice(1);

        var col3=col1.slice(1,4);

        alert(col2);//'green','blue','yellow','black','browm'

        alert(col3);//'green','blue','yellow'

如果slice()方法中其中一个是负数,则利用数组长度加上该数来确定相应的位置,如果结束位置小于开始位置,返回一个空数

 

splice()删,增,改

         删:可以删除任意数量项,指定2个参数:开始和结束,如splice(0,2),删除前2

增加(插入):在指定位置插入任意数量项。指定3个参数:开始,0(要删除的项),和要插入的项,如果要插入更多的项

 

,可以插入第456,甚至更多的项,如splice(2,0,'python','red')

改(替换):指定位置插入任意数量项,且同时删除任意数量的项,需要3个参数:开始,要删除项个数,和要插入任

 

意数量项,插入和删除的项可以不相同

splice()方法永远都会返回数组,包含原始数组中被删除的(如果没有被删除任何项,则返回一个空数组)

 

 

 var col1=['red','green','blue','yellow','black','browm'];

       var remove=col1.splice(0,1);//删除第一项

        alert(col1);

        alert(remove);//red

        remove=col1.splice(1,0,'yellow','organge');

        alert(col1);

        alert(remove)//返回一个空数组

 

var col1=['red','green','blue','yellow','black','browm'];

        //查找位置:indexOf()lastIndexOf()可以接收2个参数:要查找的项和(可选的)起点位置查找

        //indexOf()方法是从数组开头位置(0)查找,lastIndexOf()从数组的末尾向前查找

        //lastIndexOf()indexOf()如果在数组中未找到返回-1,在比较第一个参数与数组中每一项,会使用全等操作符,也

 

就是说查找的项必须是一剪梅相等的

        alert(col1.indexOf('browm'))

        alert(col1.lastIndexOf('blue',-2))

        peson=[{name:'python'}]

        s=[peson]

        alert(s.indexOf(peson))

 

支持的浏览器:ie9+,firefox2+,safari3+,opera9.5+,chrome;

 

迭代方法

以下方法都接收2个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象--影响this的值,传入这些方法中的

 

函数会接收三个参数:数组值的项,该项在如数组中的位置和数组对象本身,根据下面的方法不同,这个函数执行后返回可能

 

会也可能不会方法的返回值

以下方法不会修改数组中包含的值

 

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

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

forEach():对数组中每一项运行给定的函数,这个方法没有返回值;

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

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

 

every()some():匹配数组中的项是否满足某个条件,

every():传入函数必须对每一项返回是true,这个方法才返回true,否则为false

some()传入的函数对数组中某一项返回true,就会返回true;

 

 var num=[3,3,3,3,3];

        var everyRetun=num.every(function (item,index,array) {

            return item>2

        });

        alert(everyRetun);//true

        var num=[1,2,3,4,5,4,3,2,1];

        var everyRetun=num.every(function (item,index,array) {

            return item>2

        });

        alert(everyRetun);//false

        var someRetun=num.some(function (item,index,array) {

            return item>2

        })

        alert(someRetun);//true

        fliterRetun=num.filter(function (item,index,arry) {

            return item>2

 

        })

        alert(fliterRetun);//3,4,5,4,3它会返回一个以数组形式

        //filter()只要匹配满足这个条件的情况,都会输出

         mapRetun=num.map(function (item,index,arry) {

            return item*2

 

        })

        alert(mapRetun);//2,4,6,8,10,8,6,4,2

       num.forEach(function (item,index,array) {

           //执行的语句体

       })

        //没有返回值

 

支持的浏览器:ie9+,firefox2+,safari3+,opera9.5+,chrome;

 

归并方法

2个方法都会迭代数组中所有的项,然后构建一个最终返回值

reduce():它是从数组的第一项开始,逐个遍历到最后

reduceRight():从最后一个项开始,往前遍历到第一项

2个方法都接收2个参数:1个在每一项上调用的函数和(可选的)作为归并基础的初始值;传递给reducereduceRight()

函数接收4个参数:前一个值,当前值,项索引和数组对象yp个函数返回的任何值都会作为第一个参数自动传给下一项,第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数是数组第二项

例子

 

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

        var sum=v.reduce(function (prev,cur,index,array) {

            return prev+cur

        })//看到此类函数是回调函数的哦

        alert(sum)//15

        //第一次回调,prev1cur2

        //2次回调,prev31+2,cur3(数组的第三项)

        //这个过程会持续将数组中每一项访问一次,最后输出结果

          var sum=v.reduceRight(function (prev,cur,index,array) {

            return prev+cur

        })//

        alert(sum)//15

         //第一次回调,prev5cur4

        //2次回调,prev95+4,cur3(数组的第三项)

        //这个过程会持续将数组中每一项访问一次,最后输出结果,最终这2个方法所计算的结果是一样的,原理应该也是差不多的

        //2个方法只是从位置不同出现,而运算过程(原理基本是相同的)

支持的浏览器:ie9+,firefox2+,safari4+,opera10.5+,chrome;