JavaScript
javascript简介
JavaScript 是面向 Web 的编程语言,获得了所有网页浏览器的支持,是目前使用最广泛的脚本编程语言之一,也是网页设计和 Web 应用必须掌握的基本工具
Javascript构成
ECMAScript 是 JavaScript 的标准,但它并不等同于 JavaScript,也不是唯一被标准化的规范。
实际上,一个完整的 JavaScript 实现由以下 3 个不同部分组成:
- 核心(ECMAScript):语言核心部分。
- 文档对象模型(Document Object Model,DOM):网页文档操作标准。
- 浏览器对象模型(BOM):客户端和浏览器窗口操作基础。
编写第一个JavaScript程序
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个JavaScript程序</title>
<script type="text/javascript">
document.write("<h1>Hi,JavaScript!</h1>");
</script>
</head>
<body></body>
</html>
执行JavaScript程序
<!DOCTYPE html>
<script>
alert("顶部脚本");
</script>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script>
alert("头部脚本");
</script>
</head>
<body>
<h1>网页标题</h1>
<script>
alert("页面脚本");
</script>
<p>正文内容</p>
</body>
<script>
alert("底部脚本");
</script>
</html>
javascript的几个重要概念
基本词法
JavaScript 语法就是指构成合法的 JavaScript 程序的所有规则和特征的集合,包括词法和句法。简单描述如下:
- 词法定义了 JavaScript的基本名词规范,包括字符编码、命名规则、标识符、关键字、注释规则、 运算符和分隔符等。
- 句法定义了 JavaScript的基本运算逻辑和程序结构,包括短语、句子和代码段的基本规则,如表达式、语句和程序结构等。
区分大小写
JavaScript 严格区分大小写。为了避免输入混乱和语法错误,建议采用小写字符编写代码。在以下特殊情况下可以使用大写形式:
- 构造函数的首字母建议大写。构造函数不同于普通函数。
d = new Date(); //获取当前日期和时间
document.write(d.toString()); // 显示日期
直接量
直接量(Literal)就是具体的值,即能够直接参与运算或显示的值,如字符串、数值、布尔值、正则表达式、对象直接量、数组直接量、函数直接量等。
转义序列
转义序列就是字符的一种表示方式(映射)。由于各种原因,很多字符无法直接在代码中输入或输出,只能通过转义序列间接表示。
- Unicode 转义序列方法:\u + 4位十六进制数字。
- Latin-1 转义序列方法:\x + 2位十六进制数字。
标识符
**标识符(Identifier)**就是名称的专业术语。JavaScript 标识符包括变量名、函数名、参数名和属性名。
- 第一个字符必须是字母、下划线(_)或美元符号($)。
- 除了第一个字符外,其他位置可以使用 Unicode 字符。一般建议仅使用 ASCII 编码的字母,不建议使用双字节的字符。
- 不能与 JavaScript 关键字、保留字重名。
- 可以使用 Unicode 转义序列。例如,字符 a 可以使用“\u0061”表示。
关键字
关键字就是 ECMA-262 规定的 JavaScript 语言内部使用的一组名称(或称为命令)。这些名称具有特定的用途,用户不能自定义同名的标识符。
保留字
保留字就是 ECMA-262 规定的 JavaScript 语言内部预备使用的一组名称(或称为命令)。这些名称目前还没有具体的用途,是为 JavaScript 升级版本预留备用的,建议用户不要使用。
javascript的变量
声明变量
在 JavaScript中,声明变量使用var语句。
在一个 var 语句中,可以声明一个或多个变量,也可以为变量赋值,未赋值的变量初始化为 undefined(未定义)值。当声明多个变量时,应使用逗号运算符分隔。
var a; //声明一个变量
var a,b,c; //声明多个变量
var b = 1; //声明并赋值
document.write(a); //返回 undefined
document.write(b); //返回 1
在 JavaScript 中,可以重复声明同一个变量,也可以反复初始化变量的值。
var a = 1;
var a = 2;
var a = 3;
document.write(a); //返回 3
注意:
在非严格模式下,JavaScript 允许不声明变量就直接为其赋值,这是因为 JavaScript 解释器能够自动隐式声明变量。隐式声明的变量总是作为全局变量使用。在严格模式下,变量必须先声明,然后才能使用。
赋值变量
使用等号=
document.write(a); //显示undefined
a =1;
document.write(a); //显示 1
var a;
提示:
JavaScript 引擎的解析方式是:先解析代码,获取所有被声明的变量,然后再一行一行地运行。 这样,所有声明的变量都会被提升到代码的头部,这就叫作变量提升(Hoisting)。
变量作用域
变量作用域(Scope)
JavaScript 变量可以分为全局变量和局部变量:
- 全局变量:变量在整个页面脚本中都是可见的,可以被自由访问。
- 局部变量:变量仅能在声明的函数内部可见,函数外是不允许访问的。
var a = 1; //声明并初始化全局变量
function f(){ //声明函数
document.write(a); //显示undefined
var a = 2; //声明并初始化局部变量
document.write(a); //显示 2
}
f(); //调用函数
变量类型
JavaScript 是弱类型语言,对于变量类型的规范比较松散。具体表现如下:
- 变量的类型分类不严谨、不明确,带来使用的随意性。
- 声明变量时,不要求指定类型。
- 使用过程不严格,可以根据需要自动转换变量类型。
- 变量的转换和类型检查没有一套统一、规范的方法,导致开发效率低下。
由此带来的优缺点如下:
- 优点:使用灵活,简化了代码编写。
- 缺点:执行效率低,在开发大型应用时,程序性能会受到影响。
javascript的基本数据类型
JavaScript 的数据类型分为两种:
- 简单的值(原始值):包含字符串、数字和布尔值,此外,还有两个特殊值——null(空值)和 undefined(为定义)。
- 复杂的数据结构(泛指对象):包括狭义的对象、数组和函数。
基本类型
数据类型 | 说明 |
---|---|
null | 空值,表示非对象 |
undefined | 未定义的值,表示未赋值的初始化值 |
number | 数字,数学运算的值 |
string | 字符串,表示信息流 |
boolean | 布尔值,逻辑运算的值 |
object | 对象,表示复合结构的数据集 |
使用 typeof 运算符可以检测数据的基本类型。
console.log(typeof 1); //返回字符串"number"
console.log(typeof "1"); //返回字符串"string"
console.log(typeof true); //返回字符串"boolean"
console.log(typeof {}); //返回字符串"object"
console.log(typeof []); //返回字符串"object"
console.log(typeof function(){}); //返回字符串"function"
console.log(typeof null); //返回字符串"object"
console.log(typeof undefined) ; //返回字符串"undefined"
注意:
typeof 运算符以字符串的形式返回 6 种基本类型之一,不过通过比较可以发现,typeof 返回值与上表存在两点差异,简单说明如下:
- 把 null 归为 Object 类型,而不是作为一种特殊类型(Null)的值。
- 把 function(,){} 归为 Function 类型。即把函数视为一种独立的基本数据类型,而不是 Object 类型的一种特殊子类。
布尔型
布尔型(Boolean)仅包含两个固定的值:true 和 false。其中,true 代表"真”,而 false 代表“假”。
在 JavaScript 中,undefined、null、""、0、NaN 和 false 这 6 个特殊值转换为布尔值时为 false,被称为假值。除了假值以外,其他任何类型的数据转换为布尔值时都是 true。
console.log(Boolean(0)); //返回 false
console.log(Boolean(NaN)); //返回 false
console.log(Boolean(null)); //返回 false
console.log(Boolean("")); //返回 false
console.log(Boolean(undefined)); //返回 false
javascript的进制转换
JavaScript 支持把十进制数值转换为二进制、八进制和十六进制等不同进制的数值。
十六进制数值以“0X”或“0x”作为前缀,后面跟随十六进制的数值直接量。
var num = 0x1F4; //十六进制数值
document.write(num); //返回 500
八进制数值以数字 0 为前缀,其后跟随一个八进制的数值直接量。
var num = 0764; //八进制数值
document.write(num); //返回 500
注意:
- 八进制或十六进制的数值在参与数学运算之后,返回的都是十进制数值。
- 考虑到安全性,不建议使用八进制数值,因为 JavaScript 可能会误解为十进制数值。
- 各主流浏览器对二进制数值表示方法的支持不是很统一,应慎重使用。
javascript的严格模式
ECMAscript5 新增了严格运行模式。推出严格模式的目的如下:
- 消除 JavaScript 语法中不合理、不严谨的用法。
- 消除代码运行的一些安全隐患。
- 提高编译器效率,提升程序运行速度。
- 为未来新版本的规范化做好铺垫。
启用严格模式
在代码首部添加以下一行字符串,即可启用严格模式。
"use strict"
javascript的表达式
表达式的形式
表达式是一个比较富有弹性的运算单元。简单的表达式就是一个直接量、常量或变量。
1 //数值直接量,计算后返回数值 1
"string" //字符串直接量,计算后返回字符串“string”
false //布尔直接量,计算后返回布尔值false
null //特殊值直接量,计算后返回直接量null
/regexp/ //正则直接量,计算后返回正则表达式对象
{a : 1,b : "1"} //对象直接量,计算后返回对象
[1,"1"] //数组直接量,计算后返回数组
function(a,b){return a+b} //函数直接量,计算后返回函数
a //变量,计算后返回变量的值
表达式的类型
- 定义表达式,如定义变量、定义函数。
var a = [];
var f = function(){};
- 初始化表达式,与定义表达式和赋值表达式常常混用。
var a = [1,2];
var o = {x :1,y : 2};
- 访问表达式
console.log([1,2] [1]); //返回2
console.log(({x : 1,y : 2}).x ); //返回1
console.log(({x : 1,y : 2}) ["x"]); //返回1
- 调用表达式
console.log(function(){return 1;}()); //返回1
console.log([1,3,2].sort()); //返回1,2,3
- 实例化对象表达式
console.log(new Object()); //返回实例对象
console.log(new Object); //返回实例对象
javascript new运算符
new 是一个运算符,可以创建对象,初始化实例。其语法格式如下:
new contructor(arguments)
constructor 必须是一个构造函数表达式,参数 arguments 可有可无,参数之间用逗号分隔。如果没有逗号,可以省略小括号。
下面代码使用 new 运算符实例化 Array,并演示 3 种不同的使用方法。
var a = new Array; //创建数组,省略小括号
var b = new Array(); //创建数组
var c = new Array(1,2,3); //创建数组,并初始化元素值
console.log(c[2]); //读取创建数组对象的元素值,返回3
new 被执行时,首先会创建一个新对象,然后调用指定的构造函数,并根据传入参数初始化实例最后把初始化的实例传递给新对象。
下面代码自定义类,然后使用它创建新的对象。
var a = function(){ //自定义类型函数a
this.x = 1; //属性x
this.y = 2; //属性y
};
var b = new a; //创建对象
console.log(b.x); //调用对象属性x,返回1
javascript中的括号和点号
使用中括号运算符[]
可以存取数组元素值,使用点运算符.
可以存取对象属性值。其语法格式如下:
a.b //点运算符的用法
c[b] //中括号运算符的用法
操作数 a 表示对象,操作数 b 表示属性名。如果属性值是函数,应增加小括号,实现方法调用操作。注意,操作数 b 是不能使用字符串或字符串表达式的。
操作数 c 可以是数组,也可以是对象。具体说明如下:
- 如果左侧操作数是数组,则中括号包含的操作数应是一个值为非负整数的表达式,作为下标值,用来指定元素在数组中的位置。
- 如果左侧操作数是对象,则中括号包含的操作数应是一个值为字符串的表达式,映射对象的属性名。
中括号和点号应该属于运算符范畴,但是新版本 JavaScript 把它们视为语言核心命令来使用。
使用中括号运算符[]
不仅可以存取数组元素的值,也可以存取对象属性值。
- 存取数组元素的值。
var a = [1,"x",true,{}]; //定义数组a
console.log(a[1]); //读取第二个元素的值,返回字符串"x"
a[3] = false; //为第4个元素写入false值
console.log(a[3]); //第四个元素原来的值被覆盖,返回false
- 存取对象属性的值。
var a = { //定义对象a
x : 1, //定义对象属性x
y : function() { //定义对象方法y
return 2; //返回值
}
};
console.log(a["y"] ()); //调用方法y,返回2
a["x"] = 3; //重置属性x的值
console.log(a["x"]); //读取属性x的值,返回3
使用点运算符.
可以存取对象属性的值,它比中括号灵活、方便,因为点运算符右侧可以直接指定属性名称,而不是属性名称的字符串。
var a = {x : 1}; //定义对象a
console.log(a.x); //返回1。读取对象属性a的值
a.x = 2; //重写对象属性a的值
console.log(a.x); //返回2。再次读取对象属性a的值
对于中括号运算符,可以通过变量或字符串表达式来传递特定值。
var b = "x"; //把属性x的标识符名作为字符串存储在变量b中
var a = {x : 1}; //定义对象a
console.log(a[b]); //返回1。通过变量间接获取对象a的属性x的值
console.log(a.b); //返回undefined。点运算符无法识别变量引用
下面两种方法都可以读取数组 a 的第二个元素值。虽然说 a[“1”] 中参数是一个字符串,但是中括号运算符能够把它转换为数字。
var a = ["x",true,{}]; //定义数组
console.log(a[1]); //返回true
console.log(a["1"]); //返回true
如果中括号运算符的第二个操作数为对象,会调用 toString() 方法把对象转换为字符串表示。如果是布尔值 true 和 false,将被转换为字符串 “true” 和 “false”,而不是 1 和 0。
var a = { //定义对象
"true" : 1, //定义属性“true”
"false" : 0 //定义属性“false”
}
console.log(a[true]); //返回1。把布尔值true转换为字符串“true”
console.log(a[false]); //返回0。把布尔值false转换为字符串“false”
在不确定对象属性时,使用中括号运算符来遍历对象属性会很方便,但如果使用点运算符则容易引发异常。下面代码使用中括号运算符变量客户端 window 对象的所有属性以及属性值。
for(o in window){
document.write("window." + o + "=" + window[o] + "<br />");
}
javascript label关键字
在 JavaScript 中,使用 label 语句可以为一行语句添加标签,以便在复杂结构中,设置跳转目标。语法格式如下:
label : states
label 为任意合法的标识符,但不能使用保留字。然后使用冒号分隔签名与标签语句。
由于标签名与变量名属于不同的命名体系,所以标签名与变量名可以重复。但是,标签名与属性名语法相似,就不能重名
a : { //标签名
a : true //属性名
}
使用点语法、中括号语法可以访问属性,但是无法访问标签语句。
console.log(o.a); //可以访问属性
console.log(b.a); //不能访问标签语句,将抛出异常
javascript的break和continue
JavaScript break 和 continue 关键字都可以用在 for 和 while 循环结构中,表示跳出循环;break 关键字还可以用在 switch case 选择结构中,表示结束当前的选择语句。
break 和 continue 关键字可以在中途改变循环结构和分支结构的流程方向。
break语句
break 语句能够结束当前 for、for/in、while、do/while 或者 switch语句的执行;同时 break 也可以接受一个可选的标签名, 来决定跳出的结构语句。
break label;
如果没有设置标签名,则表示跳出当前最内层结构。
下面示例设计在客户端查找 document 的 bgColor 属性。如果完全遍历 document 对象,会浪费时间,因此设计一个条件判断所有枚举的属性名是否等于“bgColor”,如果相等,则使用 break 语句跳出循环。
for (i in document) {
if (i.toString() == "bgColor") {
document.write("document." + i + "=" + document[i] + "<br />");
break;
}
}
在下面嵌套结构中,break 语句并没有跳出 for/in 结构,仅仅退出 switch 结构。
for (i in document) {
switch (i.toString()) {
case "bgColor" :
document.write("document." + i + "=" + document[i] + "<br />");
break;
default :
document.write("没有找到");
}
}
可以为 for/in 语句定义一个标签 outloop,然后在最内层的 break 语句中设置该标签名,这样当条件满足时就可以跳出最外层的 for/in 循环结构。
outloop : for (i in document) {
switch (i.toString()) {
case "bgColor" :
document.write("document." + i + "=" + document[i] + "<br />");
break outloop;
default :
document.write("没有找到");
}
}
break 语句和 label 语句配合使用仅限于嵌套的循环结构,或者嵌套的 switch 结构,且需要退出非当前层结构。break 与标签名之间不能包含换行符,否则 JavaScript 会解析为两个句子。
continue语句
continue 语句用在循环结构内,用于跳过本次循环中剩余的代码,并在表达式的值为真时,继续执行下一次循环。它可以接受一个可选的标签名,开决定跳出的循环语句。语法格式如下:
continue label;
下面示例使用 continue 语句过滤数组中的字符串值。
var a = [1,"hi",2,"good","4", ,"",3,4], //定义并初始化数组a
b = [], j = 0; //定义数组b和变量j
for (var i in a) { //遍历数组a
if (typeof a[i] == "string") //如果为字符串,则返回继续下一次循环
continue;
b[j ++] = a[i]; //把数字寄存到数组b
}
document.write(b); //返回1,2,3,4
continue 语句只能用在 while、do/while、for、for/in 语句中,对于不同的循环结构其执行顺序略有不同。
- 对于 for 语句来说将会返回顶部计算第 3 个表达式,然后再计算第 2 个表达式,如果第 2 个表达式为 true,则继续执行下一次循环。
- 对于 for/in 语句来说,将会以下一个赋给变量的属性名开始,继续执行下一次循环。
- 对于 while 语句来说,将会返回顶部计算表达式,如果表达式为 true,则继续执行下一次循环。
- 对于 do/while 语句来说,会跳转到底部计算表达式,如果表达式为 true,则会返回顶部开始下一次循环。
javascript异常处理
ECMA-262 规范了 7 种错误类型,具体说明如下。其中 Error 是基类,其他 6 种错误类型是子类,都继承 Error 基类。Error 类型的主要用途是自定义错误对象。
- Error:普通异常。与 throw 语句和 try/catch 语句一起使用,属性 name 可以读写异常类型,message 属性可以读写详细错误信息。
- EvalError:不正确的使用 eval() 方法时抛出。
- SyntaxError:出现语法错误时抛出。
- RangeError:数字超出合法范围时抛出、
- ReferenceError:读取不存在的变量时抛出。
- TypeError:值得类型发生错误时抛出。
- URIError:URI 编码和解码错误时抛出。
try/catch/finally语句
try/catch/finally 是 JavaScript 异常处理语句。语法格式如下:
try{
//调试代码块
}
catch(e) {
//捕获异常,并进行异常处理的代码块
}
finally{
//后期清理代码块
}
在正常情况下,JavaScript 按顺序执行 try 子句中的代码,如果没有异常发生,将会忽略 catch 子句,跳转到 finally 子句中继续执行。
如果在 try 子句运行时发生错误,或者使用 throw 语句主动抛出异常,则执行 catch 子句中的代码,同时传入一个参数,引用 Error 对象。
下面示例在函数体内设计一个异常处理结构,为每个子句添加一个 return 语句。调用函数后,实际返回的是“finally”,而不是“try”,因为 finally 子句必须最后执行,把 finally 子句去掉,函数才会返回“try”。
function test() {
try {
return "try";
}catch {
return "catch";
}finally {
return "finally";
}
}
console.log(test()); //返回“finally”
下面代码就是一个多层嵌套的异常结构,在处理一系列的异常时,内层的 catch 子句通过将异常抛出,就可以将异常抛给外层的 catch 子句来处理。
try { //外层异常处理结构
try { //内层异常处理结构
test(); //错误调用
}
catch(error) {
if (error.name == "ReferenceError") console.log("错误参考"); //如果是异常引用,则提示这样的信息
else throw error; //否则再次抛出一个异常,并把错误信息向上传递
}
}
catch (error) { //获取内层异常处理结构中抛出的异常
console.log("内层 try/catch 不能够处理这个错误");
}
throw语句
throw 语句能够主动抛出异常,语法格式如下:
throw expression;
下面示例在循环体内设计当循环变量大于 5 时,定义并抛出一个异常。
try {
for (var i = 0;i < 10;i++) {
if (i > 5) throw new Error ("循环变量的值大于 5 了"); //定义错误对象,并抛出异常
console.log(i);
}
}
catch (error) { } //捕获错误,其中error就是new Error() 的实例
javascript优化多分支结构
多分支结构的优化有很多好处:既方便代码维护,又可以提升代码执行效率。例如,设计有多个条件,只有当多个条件都成立时,才允许执行特定任务。
if (a) {
if (b) {
if (c) {
if (d) {console.log("所有条件都成立!"); }
else {console.log("条件 d 不成立!"); }
} else {console.log("条件 c 不成立!"); }
} else {console.log("条件 b 不成立!"); }
} else {console.log("条件 a 不成立!"); }
数据映射
在多分支检测中,表达式的重复运算会影响性能。如果检测的条件满足下面两条,可以考虑使用数据映射来快速匹配,这样有助于代码的可读性,大大提高了代码的响应速度。
- 条件体的数量庞大
- 测试的条件值呈现离散状态
实现方法:通过数组或普通对象实现。
function map(value) {
switch (value) {
case 0 : return "result0";
case 1 : return "result1";
case 2 : return "result2";
case 3 : return "result3";
case 4 : return "result4";
case 5 : return "result5";
case 6 : return "result6";
case 7 : return "result7";
case 8 : return "result8";
case 9 : return "result9";
default : return "result10"
}
}
javascript优化循环结构
循环时最耗费资源的操作,任意一点小小的损耗都会被成倍放大,从而影响到程序整体运行的效率。一下两个因素会影响到循环的性能。
- 每次迭代做什么
- 迭代的次数
通过减少这两者中一个或全部的执行时间,可以提高循环的整体性能。如果一次循环需要较长时间,那么多次循环将需要更长时间。
下面使用 3 类循环语句设计一个典型的数组遍历操作。
//方法1
for (var i = 0;i < items.length;i ++) {
process(items[i]);
}
//方法2
var j = 0;
while (j < items.length) {
process(items[j++]);
}
//方法3
var k = 0;
do {
process(items[k++]);
} while (k < items.length);
减少循环
对于任何循环来说,每次执行循环体都要发生一下操作。
- 在控制条件中读一次属性(items.length)。
- 在控制条件中执行一次比较(i < itesm.length)。
- 判断 i<items.length 表达式的值是不是 true(i < items.length == true)。
- 一次自加操作(i++)。
- 一次数组查找(items[i])。
- 一次函数调用(process(items[i]))。
在循环体内,代码运行速度很大程度上由 process() 对每个项目的操作决定,即便如此,减少每次迭代中操作的总数也可以大幅度提高循环的性能。
for (var i = 0;len = items.length;i < len;i ++) {
process(items[i]);
}
var j = 0,count = items.length;
while (j < count) {
process(items[j++]);
}
var k = 0,num = items.length;
do {
process(items[k++]);
} while (k < num);
倒序循环
还可以通过改变循环的顺序来提高循环性能。通常,数组元素的处理顺序与任务无关,可以从最后一个开始,直到处理完第一个元素。倒序循环是编程语言中常用的性能优化方法。
for (var i = items.length;i --) {
process(items[i]);
}
var j = items.length;
while (j --) {
process(items.[j]);
}
var k = items.length - 1;
do {
process(items[k]);
} while (k --);
嵌套设计
循环结构常与分支结构混用在一起,但是如何嵌套就就非常讲究了。
var a = true;
for (var b = 1;b < 10 ;b ++) { //循环结构
if (a == true) { //条件判断
console.log(b);
}
}
JavaScript输出杨辉三角
设计思路
定义两个数组,数组 1 为上一行数字列表,为已知数组;数组 2 为下一行数字列表,为待求数组。假设上一行数组为 [1,1],即第二行数字。那么,下一行数组的元素值就等于上一行相邻两个数字的和,即为 2,然后数组两端的值为 1,这样就可以求出下一行数组,即第三行数字列表。求第四行数组的值,可以把已计算出的第三数组作为上一行数组,而第四行数字为待求的下一行数组,
实现代码
使用嵌套循环结构,外层循环遍历高次方的幂数(即行数),内层循环遍历每次方的项数(即列数)。
function print(v){
if (typeof v == "number") {
var w = 30;
if(n>30) w = (n-30) + 40;
var s = '<span style="padding:4px 2px;display:inline-block;text-align:center;width:' + w + 'px;">'+v+'</span>';
document.write(s);
}else{
document.write(v);
}
}
var n = prompt("请输入幂数:",9);
n = n - 0;
var t1 = new Date();
var a1 = [1,1];
var a2 = [1,1];
print('<div style=text-align:center;">');
for (var i = 0;i <=n;i++){
for (var j = 1; j < i + 2; j++) {
print(c(i,j));
}
print("<br />");
}
print("</div>");
var t2 = new Date();
print("<p style='text-align:center;'>耗时为(毫秒):"+(t2-t1)+"</p>");
function c(x,y){
if ((y == 1) || (y == x + 1)) return 1;
return c(x-1,y-1) + c(x-1,y);
}
javascript定义字符串
字符串直接量
使用双引号或单引号包含任意长度的文本。
var s = "true"; //把布尔值转换为字符串
var s = "123"; //把数值转换为字符串
var s = "[1,2,3]"; //把数组转换为字符串
var s = "{x : 1; y : 2}"; //把对象转换为字符串
var s = "console.log('Hello,World')"; //把可执行表达式转换为字符串
构造字符串
使用 String() 类型函数可以构造字符串,该函数可以接收一个参数,并把它作为值来初始化字符串。
var s = new String(); //创建一个空字符串对象,并赋值给变量s
var s = new String("我是构造字符串"); //创建字符串对象,初始化之后赋值给变量s
使用字符编码
使用 fromCharCode() 方法可以把字符编码转换为字符串。该方法可以包含多个整数参数,每个参数代表字符的 Unicode 编码,返回值为字符编码的字符串表示。
var a = [35835,32773,24744,22909], b = []; //声明一个字符编码的数组
for (var i in a) { //遍历数组
b.push(String.fromCharCode(a[i])); //把每个字符编码都转换为字符串存入数组
}
console.log(b.join("")); //返回字符串“C语言中文网”
javascript编码和解码
JavaScript 定义了 6 个全局方法用于 Unicode 字符串的编码和解码
方法 | 说明 |
---|---|
escape() | 使用转义序列替换某些字符来对字符串进行编码 |
unescape() | 对使用 escape() 编码的字符串进行解码 |
encodeURI() | 通过转义某些字符对 URI 进行编码 |
decodeURI() | 对使用 encodeURI() 方法编码的字符串进行解码 |
encodeURIComponent() | 通过某些转义字符对 URI 的组件进行编码 |
deencodeURIComponent() | 对使用 encodeURIComponent() 方法编码的字符串进行解码 |
escape()和unescape()方法
escape() 方法能够把 ASCII 之外的所有字符转换为 %xx 或 %uxxxx(x表示十六进制的数字)的转义序列。从 \u000 到 \u00ff 的 Unicode 字符由转义序列 %xx 替代,其他所有 Unicode 字符由 %uxxxx 序列替代
var s = "JavaScript 中国";
s = escape(s); //Unicode编码
console.log(s); //返回字符串“JavaScript%u4E2D%u56FD”
s = unescape(s); //Unicode解码
console.log(s); //返回字符串“JavaScript 中国”
encodeURI() 和 decodeURI() 方法
ECMAScript v3.0 版本推荐使用 encodeURI() 和 encodeURIComponent() 方法代替 escape() 方法,使用 decodeURI() 和 decodeURIComponent() 方法代替 unescape() 方法。
var s = "JavaScript 中国";
s = encodeURI(s);
console.log(s); //返回字符串“JavaScript%E4%B8%AD%E5%9B%BD”
encodeURICompoent() 和 decodeURICompoent()
encodeURICompoent() 与 encodeURI() 方法不同。它们的主要区别在于,encodeURICompoent() 方法假定参数是 URI 的一部分,例如,协议、主机名、路径或查询字符串。因此,它将转义用于分隔 URI 各个部分的标点符号。而 encodeURI() 方法仅把它们视为普通的 ASCII 字符,并没有转换。
var s = "c.biancheng.net/navi/search.asp?keyword=URI";
a = encodeURI(s);
console.log(a);
b = encodeURICompoent(s);
console.log(b);
javascript Base64编码和解码
Base64 是一种编码方式,可以将任意字符(包括二进制字符流)转成可打印字符。JavaScript
- btoa():字符串或二进制值转为 Base64 编码。
- atob():把 Base64 编码转为原来的字符。
- Base64 方法不能够操作非 ASCII 字符。
function b64Encode (str) {
return btoa(encodeURIComponent(str));
}
function b64Decode (str) {
return decodeURIComponent(atob(str));
}
var b = b64Encode('JavaScript 从入门到精通');
var a = b64Decode(b);
console.log(b); //返回SmF2YVNjcmlwdCVFNCVCQiU4RSVFNSU4NSVBNFOSU5NyVBOCVFNSU4OCVCMCVFNyVCMiVCRSVFOSU4MCU5QQ==
console.log(a); //返回“JavaScript 从入门到精通”