第一二三章:
1、<script>元素:
async:立即下载此脚本,但不影响页面其他操作,但不能保证脚本执行顺序,使用语法为async="async"
defer:脚本被延迟到文档被完全解析并显示之后执行,一般可以保证脚本按定义顺序执行,使用语法为defer="defer"
src:表示包含要执行代码的外部文件,可以是应用内也可以是外部域的代码,如果是后者,代码的维护者必须是你所信任的人
type:表达MIME类型,一般是(默认) type="text/javascript"
2、细节注意:一个script标签内要么是一段java代码要么是代码引用,不可混合,否则java代码会被忽略;
3、一般来说我们将script放在页面底部,即body标签内的html最后
4、ECMAScript语法:
1)var定义一个局部变量
2)typeof操作符:"undefined","boolean","string","number","object","function"
"undefined":定义但没有初始化的变量,typeof参数为为声明标识符时,返回也是undefined????
"boolean":两个字面值true和false,但true不一定是1,false不一定是0????
"NaN":本来要返回数值但未返回数值的情况(jsp一般不会报错)
3)可以使用for-in语句(类似python),如:
for(var i in window){
document.write(i);
}
4)函数:某种意义上函数签名不是必要的,签名的形参是可有可无的,数量也是任意的,换句话说,签名里面的形参只是方便函数体的使用。形参完全可以使用:arguments[num]来调用,函数调用时输入的实参可与形参数目不同,但可以通过arguments来使用。
arguments在函数体中是实时更新的。
形参的不必要性意味着通常意义上的重载不能实现,但可以通过检测参数来模仿重载,如:
function doAdd(num1,num2){
if(arguments.length==1){alert(num1+10);}
else if(arguments.length==2){alert(num2+10);}
\\.....
}
第四章:变量、作用域和内存问题
1、基本数据类型:
Undefined、Null、Boolean、Number、String(注意字符串也是)
2、基本数据类型传值、引用数据类型传地址,即都是传值,没有真正意义上的引用类型,这与java语法一致
3、作用域:
jsp的作用域仅有局部作用域(函数),没有块级作用域!
if(true){
var color = "blue";
}
alert(color); //"blue"
尤其是循环中:
for(var i=0;i<10;i++){
doSomething();
}
alert(i); //10
4、垃圾收集原理
JavaScript的对象使用标记清除(同java),但对于BOM和DOM的元素使用的是不方便的引用技术,在循环引用的时候会出现问题:
引用计数在一个引用类型变量赋值给另一个变量的时候,这个值的引用次数加一;这个变量又取另一个值的时候,引用类型的引用次数减一。在循环引用的情况就会出现问题。
function problem(){
var objectA = new Object();
var objectB = new Object();
objectA.someObject = objectB;
objectB.otherObject = objectA;
}
//在函数结束后,A、B两个对象引用次数都减一(2-1),但仍无法被清除
上面这个例子不是很恰当,因为原生的jsp对象已经全部改用标记清除了,结合DOM元素可以有这个例子:
//还看不懂,p80
注:及时赋null优化性能
5、检测类型
var s = "Nicholas"
alert(typeof s);
alert(person instanceof Object); //true
第五章、引用类型
1、Object类型:
创建实例:
var person1 = new Object();
person1.name = "Nicholas";
person1.age = 29;
var person = {
name : "Nicholas";
age : 29
}
属性为非标识符时可通过“[ ]”来代替“.”,person.name和person["name"]是等价的
2、Array类型
创建实例:
var colors = new Array();
如果提前确定项数,可以:var colors = new Array(20);
也可以:var names = new Array("Greg");
数组操作:
colors[0] = "wyn"; //修改
colors[1] = "hi"; //添加
colors.length = 1; //删除末尾若干项,使长度为1
alert(colors[1]); //Undefined无法访问
检测数组:
使用Array.isArray()方法,如果使用instanceof方法的话可能会因为不同环境下的Array构造方法不同而产生不同的结果
if(Array.isArray(value)){
//对数组进行操作
}
转换方法:
var person1 = {
toLocalString : function(){
return "laowang"
}
toString: function(){
return “wanghj”
}
}
var persond = [person1,person2]; //略去person2定义
alert(persons); //对数组的每个元素调用toString方法
alert(persons.toString()); //对数组的每个元素调用toString方法
alert(persons.toLocalSting()); //对数组的每个元素调用toLocalString方法
3、其他的数据类型(未看p90)
4、Date类型
创建实例:var now = new Date();
创建特定时刻的实例:var someDate = new Date(52545254); //使用毫秒数作为参数
格式转换:Date.parse("May 25,2004"); //格式因地区而异
Date.UTC(2005,4,5,17,55,55); //推荐使用,月份0-11,未填写的部分按最小值,月份日期为1,时分秒等为0
5、RegExp类型(正则表达式)
格式: var expression = /pattern/flags;
标志flag有:
g:全局模式,应用于所有字符串
i:不区分大小写
m:多行模式
var pattern1 = /at/g; //匹配所有“at”的实例
var pattern2 = /[bc]at/i; //匹配第一个“bat”或“cat”实例,不区分大小写
var pattern3 = /.at/gi; //匹配以at结尾的实例,所有,不区分大小写
var pattern 4 = /\[bc\]at/i; //匹配第一个[bc]at实例,不区分大小写
实例属性(对应flag),如
alert(pattern1.global); //true
实例方法(未看p106)
6、Function类型:
函数名实际上只是一个指向函数对象的指针,即函数是实例,函数名是指针
创建实例:
function sum(num1,num2){
return num1+num2;
}
var sum = function(num1,num2){
return num1+num2;
}
两者是基本一样的,但上面是函数声明下面是函数表达式,即只有上面这种写法会让浏览器将函数体提前,也就是说:
alert(sum(10,10)); //会报错,找不到函数声明
var sum = function(num1,num2){
return num1+num2;
}
作为值的函数(重点、松耦合):
场景:你想要对数组排序使用sort方法,但是sort方法要传入一个函数作为排序依据(函数作值),比如比成绩、比年龄,但你不想将排序依据函数耦合在sort上,比如你想将排序对象作为参数输入排序依据函数,这样就可以动态生成排序依据,进一步动态排序了,那么你可以这样写:
function createCompareFunction(property){
return function(object1,object2){
var value1 = object1[property];
var value2 = object2[property];
if(value1<value2)....else if()......... //比较,返回1,-1,0,这里的比较也可能要在类里面定义
}
}
var data = [{name:"a",age:1},{name:"b",age:2}];
data.sort(createCompareFunction("name"));
data.sort(createCompareFunction("age"));
函数的内部属性(松耦合):
使用arguments.callee():调用当前函数
使用function.caller():调用上级函数
function factorial(num){
return num*arguments.callee(num-1); //略去了基本情况的递归
}
//测试callee
var trueFactorial = factorial;
factorial = function(){
return 0;
}
alert(trueFatorial(1)); //ok
alert(fatorial(1)); //返回0
//caller
function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller); //调用outer()
}
注:在严格模式下,caller和callee都不可用
函数属性和方法(未看p116)
7、基本包装类型
8、单体内置类型
网友评论