一、 JavaScript
做BS系统,JavaScript的使用是少不了的;本文就带你快速回顾一下JavaScript的基本知识,看看哪些基础知识是你所遗漏的
1. js介绍
① js是一种基于对象和事件的脚本语言,使用浏览器来执行。
② js是解释型语言,无需编译就可随时运行。
③ 安全性:不允许访问本地硬盘;跨平台:有支持js的浏览器即可。
④ 在网页中编写js代码推荐使用外部引用的方式,这样可以多个页面共享js代码,达到代码复用。
2. js语法
(1) 大小写敏感,严格区分大小写。
(2) 定义字符串,可以使用“双引号”,也可使用“单引号”,推荐使用单引号与html避免冲突。
(3) js是“弱类型”语言,支持“动态类型”,没有显示数据类型,声明变量都用var
(4) 网页中的js代码应该放到<script></script>标签中,<script>标签可以放到<head>、<body>等任意位置,并且一个页面可以有不止一对<script></script>标签。
(5) 每条语句后用“;”来结尾,可以方便做js压缩并且提高代码可读性
(6) 变量命名规则:以字母、下划线或$开头,中间可以包括字母、数字、下划线或$
(7) 关键字、保留字
关键字:break、else、new、var、case、finally、return、void、catch、for、switch、while、continue、function、this、with、default、if、throw、delete、in、try、do、instanceof、typeof
保留字:abstract、enum、int short、boolean、export、interface、static、byte、extends、long、super、char、final、native、synchronized、class、float、package、throws、const、goto、private、transient、debugger、implements、protected、volatile、double、import、public
(8) 注释
单行注释: // ;块级注释:/* */;推荐使用单行注释
(9) 数据类型
js中有5种简单数据类型(也称为基本数据类型):Undefined(未定义) 取值-undefined、Null(空对象) 取值-null、Boolean(布尔) 取值-true或false、Number(数字) 取值-所有数字,包含整数和小数,范围相当于double、String(字符串) 取值-。还有1种复杂数据类型——Object(对象类型) 取值-任何对象,本质上是由一组无序的名值对组成的。
typeof运算符用来检测变量的数据类型
"undefined"——如果这个值未定义;
"boolean" ——如果这个值是布尔值;
"string" ——如果这个值是字符串;
"number" ——如果这个值是数值;
"object" ——如果这个值是对象或null;
"function" ——如果这个值是函数;
(10) 其它语句如if、while、for等等与C#几乎一致
(11) 转义字符“\”也与C#一样
3. js进阶
(1) ==与===
==、!=:对于其两边的表达式,如果类型相同,则直接比较,如果不同,则尝试转换成为相同类型再判断;==认为null与undefined、undefined与undefined是相等的
===、!==:判断前不进行类型转换,===两边必须类型相同、值也相同时才会返回true
(2) null与undefined
null:表示一个有意义的值,表示“无值”或“无对象”,变量的状态为已知状态;通过设置对象为null,来释放对对象的引用,以便浏览器回收内存。
undefined:
① 声明变量但未赋值时,变量的值为undefined
② 方法没有return语句返回值时,返回undefined
③ 未声明的变量,通过typeof()检测变量时,返回"undefined"字符串。
④ 访问不存在的属性时返回undefined
注:把null转换为数字,结果为0。而把undefined转换为数字结果为NaN。
(3) 判断变量是否可用
变量不可用:变量声明未赋值、变量未声明就使用、变量值为null
判断:
if(typeof(v) !='undefined' && v != null)
推荐写法:if(v) --这里会把v先转换为boolean类型再判断 ;对于null、undefined、0、空字符串就会转换为false
(4) 变量作用域
① 全局变量:在页面上直接声明的变量,“全局”是指在整个当前页面都能访问到的变量;
默认属于windows成员
直到页面关闭或浏览器关闭才释放资源
在每个<script></script>中都可以访问到
容易引起“命名冲突”
② 函数内部变量:作用范围为当前函数内部
③ 没有块级作用域范围,所以在方法中任何地方声明的变量都是在整个方法中有效。
④ 声明变量可以用“var”,也可不用,不用“var”声明的变量是全局变量;
⑤ js中同样不能有重名的变量,js发现变量重复后悔自动忽略后面的声明,只是用第一次声明的变量
注:推荐在js声明变量时要用var,且少使用全局变量
(5) 数据类型转换
① 字符串转化数字
字符串转换为整数:parseInt(numString, [radix]) radix 为要解析的字符串的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
字符串转化为小数:parseFloat(numString)
② 任意类型到指定类型
转为字符串:String(object)、对象.toString()
转为Boolean:Boolean(object)
转化为数字:Number(object)
③ NaN:当某类型转化为数字失败时,返回NaN,表示不是一个数字;NaN不等于任何值,包括它自己,判断时需要使用isNaN(arg)函数
(6) eval() 函数
eval() 函数可将字符串转换为代码执行,并返回一个或多个值.
如果eval函数在执行时遇到错误,则抛出异常给调用者.
类似的函数是loadcode ,loadcode并不立即执行代码,而是返回一个函数对象.
并且loadcode支持路径参数,eval并不支持. eval并不支持代码中的return语句,而是将代码作为表达式直接计算出结果.
注:不推荐使用,效率低且不安全
(7) String对象
① length属性:获取字符串的字符个数。(无论中文字符还是英文字符都算1个字符。)
② charAt(index)方法:获取指定索引位置的字符。(索引从0开始)
③ indexOf(‘字符串’,startIndex)方法:获取指定字符串第一次出现的位置。startIndex表示从第几个开始搜索。
④ split(‘分隔符’,limit);//根据分隔符将一个字符串返回为一个数组。limit表示要返回的数组的最大长度(可自定义)。多个
隔符使用正则表达式:var msg = 'a★b★c☆d☆e#f';var vals = msg.split(/☆|★|#/);alert(vals);
⑤ substr(startIndex,len)//从startIndex开始,截取len个字符。
⑥ substring(startIndex,stopIndex)//从startIndex开始,截取到stopIndex位置(不包括stopIndex所在的字符)。
⑦ toUpperCase()//转换大写、toLowerCase();//转换小写
⑧ match()、replace()、search()方法,正则表达式相关
(8) 普通函数
-->基础
① 使用function关键字
② 无返回值类型
③ 无参数的类型
④ JavaScript中函数永远有返回值,如果没有执行return语句,则返回undefined。(把函数当做“构造函数”时,return语句将不返回)
⑤ 易错:自定义函数名不要与不要和js内置、dom内置等系统函数名重名。如selectAll、focus等函数名不要用
⑥ 函数名称采用“驼峰命名法”,而非C#中的帕斯卡命名法
-->函数重载
① js中没有重载的概念,当遇到多个重名的方法后,最后一个方法定义会覆盖前面的所有方法定义
② 利用arguments实现js函数重载:通过arguments对象可以判断用户在调用函数时,是否传递了参数,以及传递了几个参数,相当于C#中的params,它是用起来像数组的一个对象,但arguments对象本身并不是数组对象。
③ 例子
function add(){
var sum = 0;
for(var i =0; i < arguments.length; i++){
sum += arguments[i];
}
}
注:推荐使用“命名参数”增加程序可读性
-->“函数”即“对象”
① 对象成员
length属性,获取方法命名参数的个数
prototype属性、arguments属性(函数执行时才可获取)
toString()方法,获取方法的源代码
② 例子
<script type="text/javascript">
function getUserName() {
var first_name = ‘Li';
var last_name = ‘Li';
return last_name + first_name;
}
//此时user_name中为函数getUserName()执行完毕后的返回值
//var user_name = getUserName(); //此时user_name就相当于是函数getUserName
var user_name = getUserName;
alert(user_name); //相当于user_name.toString()获取函数的源代码
alert(user_name.length); //获取函数的参数的个数
var result = user_name(); //调用该函数
alert(result);
</script>
(9) 调试与排错:可以利用vs和chrome、firefox浏览器中设置断点进行调试
4. js高级
(1) 函数声明与变量声明预解析
① 函数预解析:在页面中的所有函数定义语句,都会在代码执行前进行“预解析”,在“预解析”的时候,对于重名的函数就会用最后一次定义覆盖所有前面的定义。
② 变量声明预解析:对于在函数内部定义的局部变量,无论是定义在函数的任何位置,在函数执行前也会进行“预解析”,会把变量声明语句“置顶”解析。也就是说无论变量声明语句在函数的任何地方,都会被认为是写在了函数一开始的部分,所以后面的语句都可以直接使用这些变量了。但注意:这里只会把变量声明的语句“预解析”,赋值语句并不会一同被“解析”。
(2) 匿名函数
将函数定义语句当做一个表达式来处理,它可以减少函数命名问题,并且减少文件的字节数。
① 写法一:
var fn = function (x, y) { return x + y; };(勿忘分号) 调用:alert(fn(10,20)); 应用之一:设置事件处理程序。
② 写法二:
var result = (function (x, y) { return x + y; })(10, 20); 调用:alert(result);
③ 写法三:
var fn = new Function("x,y,z", "var sum=x+y+z;alert(sum);"); 调用:fn(10, 20, 30);
(3) 数组
① 介绍:js中通过Array对象创建数组,它是集成数组、ArrayList集合、Hashtable集合、栈集合、队列集合等的一个“超强综合体”
② 使用:var ages = new Array();ages[0]=10;ages[1]=16;
通过for循环来遍历:for(var i=0;i<ages.length;i++)
注:用length来获取数组元素中的个数
③ 其它声明方式
new Array(size)//声明数组初始长度为size
new Array(a,b,c…)//声明数组并设置初始值
推荐使用数组字面量:var arr =[12,‘ok’,true]
④ 没有多维数组,只能嵌套数组 :var arr = [12, ‘ok’,[‘abc’,false]]
⑤ Array的方法:toString,join,reverse、concat、sort、push、pop、shift、unshift、slice、splice等等
⑥ Array键值对集合:键值对声明 var arr={'dawei':'大卫','jim':'吉姆'};
Array数组本身就是一个键值对集合,“普通数组”,即通过下标来获取元素,只不过是一个“特殊的键值对集合”而已,把下标作为“键”,把数组元素最为值。
当键是整数时认为是“普通数组”,length属性具有长度。
当键是非整数字符串时认为是“键值对集合”。
不建议将“普通数组”与“键值对集合”混用。
遍历:
for (var key in arrayDict) {
console.log(key + '......' + arrayDict[key]);
}
(4) 面向对象
① 介绍
JavaScript中没有“类”的概念,全都是对象。“函数”是对象,通过new 关键字调用“函数”创建的也是对象。
函数本身是一个“函数对象”,而通过new关键字调用“函数”创建的对象又是另外一个对象,是两个不同的对象。
js中的面向对象也都是通过维护变量的作用域等方式来模拟的
② 构造函数
构造函数也是函数,只是调用时使用new关键字;
构造函数使用“帕斯卡”命名;
创建带参数的构造函数:通过this关键字初始化成员;
linstanceof关键字,判断对象是否属于某个“类型”(构造函数); ex:p1 instanceof Person
③ js模拟“类”
-->prototype属性
prototype是“函数对象”的属性,可实现类似C#中扩展方法的功能;
注:不要为“内置对象”随便添加新成员。防止混乱,可以对自定义对象通过该方式来添加新成员。
prototype原理图:
-->继承
js中的“继承”一般通过prototype来实现的,也可以通过apply和call来进行模拟实现
任何类型都直接或间接继承自Object
function Person(){
}
Person.prototype.hello = "hello";
Person.prototype.sayHello = function(){
alert(this.hello);
} function Child(){
}
Child.prototype = new Person();//这行的作用是:将Parent中将所有通过prototype追加的属性和方法都追加到Child,从而实现了继承
Child.prototype.world = "world";
Child.prototype.sayWorld = function(){
alert(this.world);
} var c = new Child();
c.sayHello();
c.sayWorld();
扩展:《js中call与apply用法》、《js继承的实现》
(5) 函数闭包(变量作用域问题)
在一个函数内部又定义了一个函数,内部函数函数能访问外部函数作用域范围内的变量,这时这个内部函数就叫做闭包。无论这个内部函数在哪里被调用都能访问的到外部函数作用域中的那些变量
作用:匿名自执行函数、实现缓存、实现封装、实现面向对象中的对象
扩展:《js闭包的作用》
5. 事例代码下载
注:各位园友,如果您觉得本文对你有些帮助的话,就帮我右下角推荐一下!