JavaScript基础


JavaScript是一种脚本语言,它由LiveScript改名而来,可能是为了更好地推广这个脚本语言(利用Java语言的知名度),因此Netscape 公司在最后一
刻决定将它改名为
JavaScript,但其实与Java没有什么关系。JavaScript是一种基于客户端浏览器的(现在也有服务器端,如NodeJS ),基于对象、事
件驱动式的脚本语言。
JavaScript也具有跨平台的特点。如同所有的脚本语言,JavaScript 是动态解释执行的。
JavaScript是由Netscape公司发明的,最后交给欧洲计算机制造商协会(ECMA),之后ECMAJavaScript标准化。在没有JavaScript 之前,互联网页
面都是静态内容,就像一张张写满内容的纸,
Netscape公司为了丰富互联网功能,所以在浏览器中扩展了JavaScript 支持,这样就大大扩展了互联网页
面的功能,使得互联网可以拥有丰富多彩的动画和用户交互,所以其代码通常会嵌入在
HTML 页面中。
JavaScript 的基本特点:
解释型脚本语言
程序不需要编译。
运行时才翻译成机器语言。
每执行一次就要翻译一次。所以,其效率低,并且依赖于解释器(如
googlev8 引擎),但是具有跨平台性(在各种浏览器下都支持,并且
windowslinux 等各个操作系统都能运行)。
弱类型语言,其变量在使用之前无须声明,由解释器在运行时检查其数据类型。
* 编译型语言: 程序在 执行之前需要一个专门的编译过程,把程序编译成为机器语言 的文件,运行时不需要重新翻译,直接使用编译结果就行了。
程序执
行效率高 ,依赖编译器,跨平台性差。如
CC++ 等等。
另外,编程语言分为两种,声明式编程和命令式编程。
我们可以像下面这样定义它们之间的不同:
命令式编程:命令
机器如何去做事情(how),这样不管你想要的是什么(what) ,它都会按照你的命令实现。例如,常见的命令式编程语言有:
JavaCC++JavaScriptPHP 等等。
声明式编程:告诉
机器你想要的是什么(what),让机器想出如何去做(how)。例如,常见的声明式语言有:CSSSQL

1.1 软件、程序和计算机语言
1.1.1 软件和程序
软件:软件是为了完成某些特定功能而编制的一到多个程序文件的集合。
计算机程序:是可以被连续执行的指令集合。也就是说,程序是计算机指令的序列,编制程序的工作就是为计算机编制指令序列。
1.2 计算机语言
1.2.1 机器语言
机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。它是计算机的设计者通过计算机硬件结构(电路状态,不通电

二进制的
0,通电 表示二进制的 1)赋予计算机的操作功能。 所以,机器只能直接识别01 ,于是我们可以想象当时的程序员是如何编写程序的。
1.2.2 汇编语言
汇编语言是计算机语言的一种助记符,使用符号
来表示这些固定的二进制指令的语言。
无论是汇编语言还是机器语言,都难学难记,让人看了头痛,因此我们将这种语言成为低级语言,低级语言是难以普及应用的。
1.2.3 高级语言
高级语言总是尽量接近
高级动物 的自然语言和思维方式。程序语言的发展趋势就是:从最底层的机器语言逐步跨越计算机与客观事物之间存在的语
言鸿沟。

1.3 软件开发的基本方法与步骤
著名计算机科学家
N Niklaus Wirth教授关于程序提出了著名公式:程序=数据结构+ 算法。这个公式说明了程序的主要任务。
对于程序设计的初学者来说,首先要学会设计一个正确的程序。
通常一个简单的程序设计包含以下四个步骤:
1. 分析问题。
2. 确定数据结构和算法。
3. 编制程序。
4. 调试程序。
1.3.1 算法
1-1 : 有黑和蓝两个墨水瓶,但却错把黑墨水装在了蓝墨水瓶子里,而蓝墨水错装在了黑墨水瓶子里,要求将其互换。
1-2:计算1*2*3*4*5
Step1 1 -> p
Step2
2 -> i
Step3
p * i -> p
Step4
i + 1 -> i
Step5
i <= 5返回Step3;否则转到
Step6
Step6
:打印
p
Step7
:结束
标准流程图符号:
注意:
1. 起止框:流程图只能存在一个开始框和一个到多个结束框,开始框只能有一个出口,没有入口,结束框只有一个入口,没有出口。
2. 处理框:流程图必须只能有一个出口和一个入口同时存在。
3. 输入/输出框:可以输入输出多个数,用逗号隔开。但是输入/ 输出框只能有一个入口和一个出口。
4. 判断框:有两个出口,但是只能有一个入口。
1-3:计算1*3*5*7*9
1-4:计算1+2+3+4+...+100
1.3.2 编码实现
1. 编写源代码。
2. 浏览器引擎把代码翻译为可执行代码。
3. 执行可执行代码。
1.3.3 调试程序
1. 语法错误。
2. 逻辑错误。
3. 开发错误,开发期间出现的所有错误。
4. 运行时错误,如:存储器空间不够。
2 JavaScript 入门
2.1 技术体系
1. 浏览思维导图。
2. 介绍命令式程序语言的学习方法。
2.2 JavaScript 的运行
2.2.1运行 JavaScript
1.使用javascript:前缀构建执行JavaScript代码的URL

<a href="javascript:alert('运行js ');"></a>
<form action="javascript:alert('
运行js
');"></form>
2.绑定事件,在事件被触发的时候运行js
代码。
<button οnclick="alert('运行js ')"><button/>
3.script元素中执行js
代码。
<script type="text/javascript">
alert("
运行js
");
</script>
4.引入外部js
文件。
<script type="text/javascript" src="js文件所在的url路径 "></script>
2.2.2 Hello world
1.输出hello world

<!--在浏览器中弹出 -->
<script type="text/javascript">
alert("hello world!");
</script>
<!--
在控制台中输出
-->
<script type="text/javascript">
console.info("hello world!");
</script>
<script type="text/javascript">
var data = prompt("
请输入数据:
");
console.info(data);
</script>
2.3 JavaScript 语法
2.3.1注释
js支持两种格式的注释。在行尾“//”之后的文本都会被js当做注释忽略掉的。此外,“/* ”“ */” 之间的文本也会当做注释,这种注释可以跨行书写,单不
能有嵌套的注释。
以下注释都是合法的:
// 这里是单行注释
/*这里也是单行注释 */
/*
这里是
多行注释
*/
2.3.2
关键字
js 把一些标识符拿出来用作自己的关键字。因此,就不能再程序中把这些关键字用作标识符了。
break delete function return typeof
case do if switch var
catch else in this void
continue flase instanceof throw while
debugger finally new true with
default for null try
//
在当前版本没有使用(也作为关键字),但是在未来版本可能会使用到的一些关键字
class const enum export import super
//
此外,下面这些关键字在普通的JavaScript
代码中是合法的,但是在【严格模式】下是保留字
implements let private public yield
interface package protected static
//
【严格模式】同样对下面的标识符的使用做了严格限制,它们并不完全是保留字,但不能用做变量名、函数名和参数名
arguments eval
//
java
】中的一些关键字
abstract double goto native static
boolean enum implements package super
byte export import private synchronized
char extends int protected throws
class final interface public transient
const float long short volatile
//js
中预定义的一些【全局变量】和【函数】,应当避免把它们的名字用做变量名和函数名
arguments encodeURI Infinity Number RegExp
Array encodeURIComponent isFinite Object String
Boolean Error isNaN parseFloat SyntaxError
Date eval JSON parseInt TypeError
decodeURI EvalError Math RangeError undefined
decodeURIComponent Function NaN ReferenceError URIError
2.3.3
标识符
js 中,我们需要标识代码中的很多元素,包括函数名、变量名等。
我们选择的名称就称为标识符,并且必须遵循如下规则:
标识符不能使用关键字
标识符可以包含字母、数字
0-9、下划线(_)或美元符号($)
标识符的第一个字符必须是一个字母、下划线或美元符号。
标识符是区分大小写的,并且没有规定最大长度。

如下标识符是合法的:
identifier userName1 User_name _sys_var1 $change Public
如下标识符不合法:
1_Name *system public
2.3.4
直接量和变量
1. 直接量
12 // 数字
1.2 // 小数
"hello world" // 字符串
true false // 布尔值
/regex/ // 正则表达式
2. 变量
var x = 1;//变量x的值是数字直接量 1
相当于数学里面的,设x=1

2.3.5 语句
var num = 1;// 声明语句
if (num === 1) {//if 判断语句
alert(1);
}
3
JavaScript
数据类型
3.1 数据类型一览
3.2.1 基本数据类型
number 类型:包含整数和浮点数(即小数)。
boolean类型:只有truefalse两个值。
string 类型:字符串值必须用引号括起来,引号可以是单引号,也可以是双引号。
undefined 类型:专门用来确定一个已经创建但是没有初始值的变量。
null 类型:用于表明某个变量值为空。
1.number 类型
与强类型语言
CJava不同的是JavaScript 的数值类型不仅包含所有的整型变量,也包括所有的浮点型变量。
例如:
/*整型与浮点型 */
3 //
整型
3.14 // 浮点型
2345.789 // 浮点型
0.3333 //浮点型,值为 0.3333
.3333 //
也是浮点型
6.02e23 //浮点型,值为 6.02*10^23
1.4738223E-32 //1.4738223*10^-32
//
十六进制和八进制的暂不列举,因为用的较少
// 若运行如下代码
var a, b;
a = 5E2;
b = 1.23e-3;
console.info(a + "\n" + b);
显示结果如下:
当数值变量超出了其表数范围时,将出现两个特殊值:
Infinity(正无穷大)和-Infinity(负无穷大)。前者出现的情况是计算结果大于number 类型(数
值类型)的最大值,后者表示计算结果小于
number 类型(数值类型的最小值)。
例如:
var x = 1.7976931348623157e308;
x = x + 1e292;
console.info(x);
显示结果如下:
类似的,如果变量值小于数值变量的最小值将出现
-Infinity 值。
例如:
var x = -1.7976931348623157e308;
x = x - 1e292;
console.info(x);
显示结果如下
另外,
Infinity-Infinity 是表示正负无穷大,是数据溢出时返回的值,所以一般对其进行各种运算没什么意义,除非有特殊情况,虽然其本身也属于
number类型。在对Infinity进行运算的时候经常会得到NaN或者Infinity
JavaScript 的数值类型也可以为负数或零,例如:
var zero = 0;// 正常的零值
var negz = -0;// 正常的负值
zero === negz;//true ,正零和负零相等
1 / zero === 1 / negz;//false ,正无穷和负无穷不相等
二进制浮点数和四舍五入错误
在数学里实数其实有无数个,但是
JavaScript通过浮点数的形式只能表示其中有限的个数(确切地说是18437736874454810627 个)。也就是说,当
JavaScript 中使用实数的时候,常常只是真实值的一个近似表示。
JavaScript采用了IEEE-754浮点数表示法(几乎所有现代编程语言所采用) ,这是一种二进制表示法,可以精确地表示分数,比如1/21/8
1/1024。遗憾的是,我们通常用的分数(特别是在金融计算方面)都是十进制分数1/101/100等。二进制浮点数表示法并不能精确表示类似0.1 这样
简单的数字。
JavaScript中的数字具有足够的精度,并可以及其近似于0.1 。但事实是,数字不能精确表述的确带来了一些问题。
例如
:
var x = .3 - .2;// 30美分减去20
美分
var y = .2 - .1;// 20美分减去10 美分
x == y;//false ,两值不能
x == .1;//false.3 - .2 不等于 .1
y == .1;//true
.2 - .1等于
.1
由于舍入误差,0.30.2之间的近似差值实际上并不等于0.20.1之间的近似差值。这个问题并不只是在JavaScript
中才会出现,理解这一点非常重
要:在任何使用二进制浮点数的编程语言中都会有这个问题。同样需要注意的是,上述代码中
xy 的值非常接近彼此和最终的正确值。这种计算结果可
以胜任大多数的计算任务:这个问题也只有在比较两个值是否相等的时候才会出现。
JavaScript 的未来版本或许会支持十进制数值类型以避免这些舍入问题。在这之前你可能更愿意使用大整数进行重要的金融计算,例如,要使用整
而不要使用小数 进行基于货币单位的运算。
注:
JavaScript的真实运行环境中,0.3 - 0.2 = 0.09999999999999998
2.boolean 类型
布尔值指代真或假。这个类型只有两个值,保留字
truefalse
JavaScript 程序中的比较语句的结果通常都是布尔值。
例如:
a == 4
这段代码用来检测变量a的值是否等于4。如果等于,比较结果的布尔值就是true,如果不等,比较结果则为false

3.string 类型
JavaScript 的字符串必须用引号括起来,此处的引号既可以是单引号,也可以是双引号。
例如:
var a = "hello world";
var b = 'hello world';
单引号可以包含双引号,双引号也可以包含单引号,但是单引号不能再次包含单引号,除非使用转义符(后面会介绍),同理双引号也不能再次包含
双引号。

例如:
var str1 = 'name="Tom"';//输出结果为 name="Tom"
var str2 = "name='Tom'";//
输出结果为
name='Tom'
如果要比较两个字符串是否相等,直接使用==
运算符即可。
例如:
var a = "1";
var b = '1';
console.info(a == b);
运行结果为:true

4.undefinednull 类型
undefined类型的值只有一个undefined,该值用于表示某个变量不存在,或者没有为其分配值,也用于表示对象的属性不存在。null 用于表示变量的值
为空。
undefinednull之间的差别比较微妙,总体而言,undefined表示没有为变量设置值或属性不存在;而null表示变量是有值的,只是其值为null
但如果不进行精确比较,很多时候
undefinednull本身就相等,即null==undefined将返回为true。如果要精确区分nullundefined ,应该考虑使用精
确等于符(
=== )。
需要注意的是,
undefinednull 的派生类(即子类)。
3.2.2 引用类型
原生对象:所谓原生对象是由
JavaScript所提供的、独立于宿主环境(即浏览器)的对象,简单点说,就是在ECMA-262 标准中定义的对象。它包
括:
ObjectFunctionArrayStringBooleanNumberDateRegExpErrorEvalErrorRangeErrorReferenceError
SyntaxErrorTypeErrorURIErrorArgumentsJSON
内置对象:内置类对象
JavaScript中提供的、独立于宿主环境对象,这些对象在JavaScript 程序执行时就已经存在。内置对象实际上也是原生对象
的一种,但是与原生对象不同的是,内置对象不需要显式的初始化,因为它已经初始化了。
ECMA-262中只定义了两个内置对象:Global
Math
宿主对象:宿主对象指与宿主环境即浏览器有关的对象。所有的
BOMDOM 对象都是宿主对象。
3.2.3 内存分布
1. 基本数据类型值是存储在栈内存中的,并且里面直接存入基本类型值所对应的二进制数据。
2. 引用类型数据值也是存储在栈内存中的,但是引用不包含它所指向的对象的实际数据,而是指向内存中对象所在的位置。
3.3 数据类型转换
3.3.1 自动转型
JavaScript 支持自动类型转型,这种类型转换的功能非常强大。
例如:
var a = "3.145";
var b = a - 2;//
字符串与数字相减
var c = a + 2;// 字符串与数字相加
console.info(b + "\n" + c);
结果为:
1.145
3.1452

在上面代码中,a是值为3.145的字符串,让a和数值执行减法,则自动执行算术运算,并将a的类型转换为数值;让a和数值执行加法,则2
转换为字符
串。这就是自动类型转换,它的转换规律是:
对于减号运算符,因为字符串不支持减法运算,所以系统自动将字符串转换成数值。
对于加号运算符,因为字符串可用加号作为连接运算符,所以系统自动将数值转换成字符串,并将两个字符串进行连接运算。
又例如:
10 + " objects"; //"10 objects",数字10 转换为字符串
"7" * "4"; //28 ,两个字符串均转换为数字
var n = 1 - "x"; //NaN,因为"x" 无论如何都无法转换为数字
n + " objects"; //"NaN objects"NaN转换为字符串 "NaN"
各种类型自动类型转换的结果
目标类型
字符串类型数值类型布尔型对象
undefined "undefined" NaN false Error
null "null" 0 false Error
字符串不变数值或NaNtrue String对象
空字符串不变0 false String对象
0 "0" 0 false Number对象
NaN "NaN" NaN false Number对象
Infinity "Infinity" Infinity true Number对象
-Infinity "-Infinity" -Infinity true Number对象
数值数值字符串不变true Number对象
true "true" 1 不变Boolean
false "false" 0 不变Boolean对象
对象toString()返回值valueOf(),toString()NaNtrue 不变

3.3.2 强制转型
1. 转换成字符串
toString() 函数
toString()方法是来自于原生对象Object,因所有对象都继承自Object,所以所有对象都有toString()方法。另外,由于booleannumberstring 这三
个基本类型可看作伪对象,即可看成引用类型的
BooleanNumberString,所以也可使用toString()
注:
nullundefined没有toString()
例如:
var flag = false;
console.info(flag.toString());
输出结果:
"false"
另外,Number类型的toString()方法比较特殊,它有两种模式,即默认模式和基模式。采用默认模式,toString()
方法只是应用字符串输出数值。
例如:

var num = 10;
console.info(num.toString());
输出结果:
"10"
采用基模式转换:
var num = 10;
console.info(num.toString(2));
console.info(num.toString(8));
console.info(num.toString(16));
输出结果:
"1010"
"12"
"A"
String()
函数
String()可以把任何值转换成字符串,这种强制转换和toString()的唯一不同之处在于,对于nullundefined 值也能强制转换而不会报错。
例如:
var str = String(null); //"null"
var strObj = null;
console.info(strObj.toString());//
报错
2. 转换成数字
parseIntparseFloat是来源于内置对象Global的两个方法,而Number则是来源于原生对象Number
parseInt() 函数
parseInt() 方法首先查看位置0 处的字符,判断它是否是个有效数字;如果不是,该方法将返回NaN ,不再继续执行其他操作。但如果该字符是有效数
字,该方法将查看位置
1 处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt() 将把该字符之前的字符串转换
成数字。
例如:
var num = parseInt("12345px");//返回 12345
var num1 = parseInt("0xA"); //10
var num2 = parseInt("56.9"); //56
var num3 = parseInt("red"); //NaN
//
基模式
var num4 = parseInt("10", 8); //8
parseFloat()
函数
parseFloat() 方法与parseInt() 方法的处理方式相似,从位置0 开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转
换成整数。 不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。
parseFloat() 会把这个
小数点之前的字符转换成数字。这意味着字符串
"11.22.33"将被解析成11.22。 使用parseFloat() 方法的另一不同之处在于,字符串必须以十进制形
式表示浮点数,而不是用八进制或十六进制。该方法会忽略前导
0,所以八进制数0102 将被解析为102。对于十六进制数0xA,该方法将返回NaN
因为在浮点数中,
x 不是有效字符。(注释:经测试,具体的浏览器实现会返回0,而不是NaN 。)
var fNum1 = parseFloat("12345red"); //返回 12345
var fNum2 = parseFloat("0xA"); //
返回
NaN
var fNum3 = parseFloat("11.2"); //
返回
11.2
var fNum4 = parseFloat("11.22.33"); //
返回
11.22
var fNum5 = parseFloat("0102"); //
返回
102
var fNum1 = parseFloat("red"); //
返回
NaN
Number()函数

Number() 函数的强制类型转换与parseInt() parseFloat() 方法的处理方式相似,只是它转换的是整个值,而不是部分值。 还记得吗,parseInt()
parseFloat() 方法只转换第一个无效字符之前的字符串,因此"1.2.3" 将分别被转换为"1" "1.2"。 用Number() 进行强制类型转换,"1.2.3" 将返回
NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number()将判断是调用parseInt() 方法还是parseFloat() 方法。
Number(false); //0
Number(true); //1
Number(undefined); //0
Number(null); //0
Number("1.2"); //1.2
Number("12"); //12
Number("1.2.3"); //NaN
Number(new object()); //NaN
Number(false); //0
3.
转换成布尔值
Boolean() 函数
当要转换的值是至少有一个字符的字符串、非
0数字或对象时,Boolean()函数将返回true。如果该值是空字符串、数字0undefinednull ,它将
返回
false
var b1 = Boolean(""); //false - 空字符串
var b2 = Boolean("hello"); //true - 非空字符串
var b3 = Boolean(50); //true - 非零数字
var b4 = Boolean(null); //false - null
var b5 = Boolean(0); //false -

var b6 = Boolean(new object()); //true - 对象
4 JavaScript 运算符
JavaScript提供了相当丰富的运算符,运算符也是JavaScript语言的基础。通过运算符,可以将变量连接成语句,语句是JavaScript 中的执行单位。
4.1 操作数
4.1.1 操作数的个数
运算符可以根据其操作数的个数进行分类。
JavaScript中的大多数运算符(比如“*”乘法运算符)是一个二元运算符(binary operator ),将两个表达式合
并成一个稍复杂的表达式。换而言之,他们的操作数均是两个。
JavaScript同样支持一些一元运算符(unary operator ),它们将一个表达式转换为另
一个稍复杂的表达式。表达式
-x中的“-”运算符就是一个一元运算符,是将操作数x求负值。最后,JavaScript支持一个三元运算符( ternary
operator
),条件判断运算符“?:”
,它将三个表达式合并成一个表达式。
4.1.2 操作数类型和结果类型
一些运算符可以作用于任何数据类型,但任然希望他们的操作数是指定类型的数据,并且大多数运算符返回一个特定的值。
4.2 运算符
4.2.1 赋值运算符
JavaScript使用“=” 运算符来给变量或属性赋值。
例如:
var str = "javascript";
var pi = 3.14;
var visited = true;
另外也可以变量赋值:
var str = "javascript";
var str2 = str;
连续赋值也可:
var b, c;
var a = b = c = 10;//
最后三个变量均为
10
4.2.2
算术运算符
1.“+” 运算符
二元加法运算符
“+” 可以对两个数字做加法,也可以做字符串连接操作:
1 + 2 //3
"hello" + " world" //"hello world"
如果既有字符串又有数字,则数字会自动转型会字符串。
1 + "2" //"12"
另外,如果有个操作数是对象,那么对象会转换为原始值。
例如:
1 + {} //"1[object Object]"
true + true //2
1 + null //1
1 + undefined //NaN
2.“-”减号、“*”乘号、“/”除号、“%”
取模
var c = 5.2;
var d = 3.1;
var sub = c - d;
console.info(sub);//2.1
var e = 5.2;
var f = 3.1;
var product = e * f;
console.info(product);//16.12
var a = 30;
var b = 4;
console.info(a / b);//7.5
var x = 5;
var y = 2;
var mod = x % y;
console.info(mod);//1
3.
自增自减
++为自增,--是自减,都是单目运算。运算符出现在变量之前时,称为前缀形式,表示变量在使用之前自动加1或减1
例如:
var i = 1;
i++;//
就相当于
i = i + 1;
又例如:
var b = 5;
var a = ++b + 6;
console.info(a + "\n" + b);
结果为:
12
6
若是出现在变量之后,称为后缀形式,表示变量再使用之后再自动加1或减
1.
如:
var i = 1;
var j = i++;
console.info(j);
console.info(i);
结果为:
1 2
但是你需要注意的是如下情况:
var i = 0;
i = i++;
console.info(i);
是不是觉得结果很让人费解? 接下来我们来看看这是为什么。
首先我们来分析之前的一段代码:
var i = 1;
var j = i++;
这段代码运行到j=i++的时候会率先处理赋值运算符,但是由于有后置++,在JavaScript中只要出现后置++并且在准备运算拥有后置++
的变量时马上
会出现如下的情况:
我们的计算机会马上将
i的值赋值给一个临时的i temp,再此之后,还有一个关键的步骤,则是马上让i 本身加上1
如图:
之后呢,我们就会马上去执行赋值运算符,将
i的值赋值给j ,请注意:这个时候是将i temp 的值赋值给j ,然后将i temp 销毁掉。
如图:

如图:
同理,我们来推论如下代码。
var i = 0;
i = i++;
当执行到i = i++;时,显然计算机会先处理赋值运算符,再来处理后置++,但是还是要注意的是,我们只要遇到后置++的时候i
变量所在的内存区域
依然会发生如下的变化:
接着就开始执行赋值运算,并清除
i temp ,如图所示:
:
每当我们遇到后置++或后置--的时候,我们所说的最后让它执行++运算符的意思是最后使用它的i temp来进行下一步的运算,但是在运算之前,
已经
确定好了
i的值和i temp的值,并且i i temp 的值在确定的时候是不一样的。
例题
1
x=5
1)
那么y=++x表达式的xy
结果分别是多少?
2)y=++x*++xxy 的计算结果为多少?
例题
2
x=5
y=x--
xy
计算结果?
y=x++*x++xy 计算结果?
例题
3
a=6
c=a+(++a)+(--a)-(a++)
ac
的计算结果?
a=a+(++a)+(--a)-(a++)a 的计算结果?
4.2.3 带操作的赋值运算符
赋值运算符可以与算术运算符等其他运算符相结合。
+=:对于x += y,即对应于x = x + y
-=:对于x -= y,即对应于x = x - y
*=:对于x *= y,即对应于x = x * y
/=:对于x /= y,即对应于x = x / y
%=:对于x %= y,即对应于x = x % y
另外, x op= yx = x op y 相比,前者只计算了一次,而后者计算了两次。
4.2.4 关系运算符
比较运算符(关系运算符)用于判断两个变量或常量的大小,比较运算符的结果是一个布尔值。
>:大于,如果前面变量的值大于后面变量的值,则返回true
>=:大于等于,如果前面变量的值大于等于后面变量的值,则返回true
<:小于,如果前面变量的值小于后面变量的值,则返回true
<=:小于等于,如果前面变量的值小于等于后面变量的值,则返回true
!=:不等于,如果前后两个变量的值不相等,则返回true
==:等于,如果前后两个变量的值相等,则返回true
!==:严格不等于,如果前后两个变量的值不相等,或者数据类型不同,都将返回true
===:严格等于,必须前后两个变量的值相等,数据类型也相同,才会返回true
例如:
console.info(5 == "5");//true
console.info(5 === "5");//false
两者的区别在于,==支持自动转型(>>=<<=也可自动转型),而===
不能自动转型。
另外,比较运算符不仅可以在数值之间进行比较,也可以在字符串之间进行比较。字符串的比较规则是按字母的
Unicode 值进行比较。对于两个字符
串,先比较它们的第一个字母,其
Unicode值大的字符串大,如果他们的第一个字母相同,则比较第二个字母…… 一次类推。
例如:
console.info("z" > "abc");// true ,排后面的字母大于前面的
console.info("abc" > "Xyz");//true ,小写字母大于大写字母
console.info("ABC" > "ABB");//true
4.2.5
逻辑运算符
逻辑运算符用于操作两个布尔型的变量或常量。
&&:且,必须前后两个操作数都为true才返回true,否则返回false
||:或,只要两个操作数中有一个为true,就可以返回true,否则返回false
!:非,只操作一个操作数,如果操作数为true,则返回false,如果操作数为false,则返回true
例如:
console.info(!false);//true
console.info(5 > 3 && '6' > 10);//false
console.info(4 >= 5 || "abc" > "abb");//true
4.2.5
其他运算符
1. 条件运算符(三目运算)
三目运算符的语法格式如下:
(expression) ? if-true-statement : if-false-statement;
三目运算符的运算规则是:先对逻辑表达式expression求值,如果逻辑表达式返回true,则执行第二部分的语句;如果逻辑表达式返回false
,则返回第
三部的语句。
例如:
5 > 3 ? alert("5大于3") : alert("5小于 3");
2.点运算符

对象 . 属性值,表示访问该对象的某个属性。
例如:
//创建一个学生对象,仅有一个name 属性
var student = {
name : "
张三
"
} c
onsole.info(student.name);
3.
转义符
符号意义
\b 代表退格
\t 表示制表符
\n 换行回车
\v 垂直的制表符
\r 回车
\" 双引号
\' 单引号
\\ 反斜线,即\
\OOO 使用八进制数表示的拉丁字母。OOO表示一个3位的八进制整数,范围时000~377
\xH 使用十六进制数表示的拉丁字母,H表示一个2位的十六进制整数,范围是00~FF
\uHH 使用十六进制数(该数值指定该字符的Unicode值)表示的字符,HH表示一个4位的十六进制整数

HHHHHH 4.typeof
typeof运算符用于判断某个变量的数据类型,它既可以作为函数来使用,例如typeof(a)可返回变量a
的数据类型;也可座位一个运算符来使用,例如
typeof a也可返回变量a 的数据类型。
不同类型参数使用
typeof 运算符的返回值类型如下:
数据返回值
undefined undefined
null object
true/false boolean
数值类型number
字符串类型string
对象object

5.instanceof
该运算符用于判断某个变量是否为指定类的实例。
例如:
var arr = [1, 2];
console.info(arr instanceof Array);//true
,因为arr对象属于Array

console.info(arr instanceof Object);//true,因为任何对象都属于Object
6. 逗号
var i = 0, j = 1, k = 2;
//
等同于如下
var i = 0;
var j = 1;
var k = 2;
4.3 运算符优先级别
优先级别运算符
1 “.”“()”“[]”
2 “!”“-”(负号)“++”(前置)“--”(前置)“typeof”“new”“void”“delete”
3 “*”“/”“%”
4 “+”“-”
5 “<<”“>>”“>>>”
6 “<”“<=”“<”“>=”
7 “==”“!=”“===”“!==”
8 “&”
9 “^”
10 “|”
11 “&&”
12 “||”
13 “?:”
14 “=”“+=”“-=”“*=”“/=”“%=”“<<=”“>>=”“>>>=”“&=”“^=”“|=”
15 "++"(后置)"--"(后置)
16 “,”

从表格中可以看出,点运算符和括号的优先级别最高,一些特殊运算符的优先级别位于第二,其次是算术运算符,再其次是位运算符,关系运算符,
逻辑运算符,三目运算,赋值运算符,最后是逗号运算符。
5 JavaScript 流程控制
JavaScript 里面有没有块作用域,只有函数作用域,即函数的花括号可以保证自己花括号内的变量不能在花括号外被使用。
例如:
var flag = 1;
if (flag == 1) {
var num = 1;
console.info(num);//
此处理所当然可以使用到
num
} c
onsole.info(num);//
因为js没有块作用域的说法,所以花括号不会分隔所用于,在花括号外依然可以使用花括号内的变量

5.1 条件判断
5.1.1简单的if 语句
if (logic expression) {
statement...
}
5.1.2 if/else
语句
if (logic expression) {
statement...
} else {
statement...
}
5.1.2 连续的if/else
语句
if (logic expression) {
statement...
} else if (logic expression) {
statement...
} else if (logic expression) {
statement...
} else {
statement...
}
5.1.3 if/else
的嵌套
if (logic expression) {
if (logic expression) {
statement...
} else {
statement...
}
} else if (logic expression) {
if (logic expression) {
statement...
} else {
statement...
}
} else {
statement...
}
5.1.4 识别各种if/else
组合
仔细阅读一下下面
if 组合。
if (logic expression) {
statement...
} i
f (logic expression) {
statement...
} i
f (logic expression) {
statement...
}
看看执行的时候与下面的有什么区别。

if (logic expression) {
statement...
} else if (logic expression) {
statement...
} else if (logic expression) {
statement...
} else {
statement...
}
再看看下面这个跟上面的有什么区别。
if (logic expression) {
statement...
} else if (logic expression) {
statement...
} else if (logic expression) {
statement...
}
最后再给你写一个看看。
if (logic expression) {
statement...
if (logic expression) {
statement...
if (logic expression) {
statement...
}
}
}
5.1.5 省略if/else
的花括号
通常,不要省略
ifelse 后执行块的花括号,但是如果语句执行块只有一行语句时,则可以省略花括号。
例如:
var a = 5;
if (a > 4) console.info("a
大于
4");
else console.info("a
不大于
4");
当然也可以这样写:
var a = 5;
if (a > 4)
console.info("a
大于
4");
else
console.info("a
不大于
4");
当然如果写成以下这样是不能正常按照你所想象的逻辑运行的。
var a = 5;
if (a > 4)
console.info("a
大于
4");
else
console.info("
代码进入了
else");
console.info("a
不大于
4");
如果你想执行这样的逻辑,建议修改为如下的代码:
var a = 5;
if (a > 4)
console.info("a
大于
4");
else {
console.info("
代码进入了
else");
console.info("a
不大于
4");
}
5.1.6 switch
语句
if语句在程序运行过程中创建一条分支,并且可以使用else if来处理多条分支。然而我们在处理多分支的实际情况的时候可以去使用switchswitch 在大
量分支的实际运用中,代码清晰,执行效率高于
if分支,因为switch使用了跳转表,有算法去跳转相应的分支并结束代码,而大量if 分支只能傻傻的一行
一行的执行。
switch 的语法形式如下:
switch(expression) {
case condition1: statement...;
break;
case condition2: statement...;
break;
...
default: statement...;
}
例如:
var score = "c";
switch(score) {
case "a": console.info("
");
break;
case "b": console.info("
");
break;
case "c": console.info("
");
break;
case "d": console.info("
");
break;
default: console.info("
成绩输入错误
");
}
另外,JavaScriptswitch语句中也可省略case块后的break语句,如果省略了case块后的break语句,JavaScript将直接执行后面case
块里的代码,不
会理会
case块里的条件,直到遇到break 语句为止。
并且
switch 语句里的变量条件可以放任何基本类型。
5.2 循环
5.2 while 循环
while 的语法形式:
while (expression) {
statement...
}
以下代码只执行一次:
var i = 0;
if (i < 2) {//
只要判断值为true
,就能执行花括号中的代码
console.info(i);
i++;
}
运行结果:

0
只需要把if替换成while
就可以达到循环的效果,以下代码可以执行多次:
var i = 0;
while(i < 2) {//
只要判断值为true
,就能执行花括号中的代码
console.info(i);
++i;
//
每执行完一次之后会再回到while
的判断语句进行判断
}
运行结果:
0 1
5.3 do while
循环
do while 的语法形式:
do {
statement...
} while(expression);
do while循环跟while循环很类似,它们的区别是while
每次执行花括号代码的时候是先会去判断是否满足括号里的条件,如果满足再去执行,如果执行
n次,这n次中的每一次都是经过判断了的。 而do_while 第一次执行花括号内容是不需要满足判断条件,它是从第一次运行完毕之后再判断是否能运
行下一次,如果满足判断条件,才能够再一次执行花括号内部的代码。
例如一个
while 循环是这样:
var i = 0;
while (i > 0) {
console.info(i);
++i;
} c
onsole.info("
循环结束
");
输出结果是:
循环结束
如果变成
do while 循环的话:
var i = 0;
do {
console.info(i);
++i;
} while(i > 0);
console.info("
循环结束
");
执行结果:
0 1 2 .
..
死循环
两者的差别是因为
do while第一次运行时不需要进行判断的,让i的值变成了1,而大于了0,显然只要让i 大于了零就可以无限运行下去了。
5.4 for循环
for循环是更加简洁的循环语句,大部分情况下,for循环语句可以替代while循环、do_while 循环。
其基本语法如下:
for (初始化0;判断1;语句 3) {
语句
2
}
执行顺序是:
step0. 初始化只执行一次。
step1.执行以后运行判断1
step2.执行语句2
step3.执行语句3,完毕之后执行step1的判断1 (故可以一直循环判断和执行)。
示例代码:
for (var i = 0; i < 3; ++i) {
console.info(i);
}
运行结果:
0 1 2
需要注意的是:
js里面由于没有块作用域,ifor 循环以外还可以重复使用。
例如:
for (var i = 0; i < 3; ++i) {
console.info(i);
} c
onsole.info(i);
运行结果:
0 1 2 3
例题:sum = 1 * 2 * 3 * ... * 100,计算sum
的值。
用三种循环分别来做,代码如下:
while 循环:
var i = 1, sum = 0;
while (i < 101) {
sum += i;
++i;
}
do while
循环:
var i = 1, sum = 0;
do {

sum += i;
++i;
} while(i < 101);
for
循环:
var i, sum;
for (i = 0; i < 101; ++i) {
sum += i;
}
小结:
for 语句和while语句会先判断循环控制条件,后执行循环体;而do while语句时先执行循环体,后进行循环控制条件的判断。for语句和while 语句可
能一次也不执行循环体;而
do while 语句至少执行一次循环体。
do whlie语句和while语句多用于循环次数不定的情况,对于循环次数确定的情况,使用for 语句更加方便。
do while 语句更适合于第一次循环肯定执行的场合。
5.4 打断循环
5.4.1 break
break是用于终止整个循环(包括whiledo_whilefor
),终止之后便开始执行执行该循环之后的代码。
需要注意的是,
break 是终止的离它最近一个循环。
示例代码如下:
for (i = 0; i < 10; ++i) {
console.info("=======");
console.info("i:" + i);
for (k = 0; k < 10; ++k) {
if (k == 3) {
break;
} c
onsole.info("k:" + k);
} c
onsole.info("
跳出最里面的for循环
");
} c
onsole.info("
跳出最外面的for循环
");
5.4.2 continue
continue
是用于终止本次循环,接着开始进行下一次循环。
需要注意的是,
continue 也是终止的离它最近的一个循环的某一次执行而进行该循环的下一次执行。
示例代码如下:
for (i = 2010; i <= 2045; ++i) {
if (i == 2015) {
console.info("
小明说:我们分手吧!
”");
continue;//
是终止本次循环(离continue
最近的循环)
} c
onsole.info("
" + i + "年的时候:小明跟小红在一起!
");
}
执行之后可以看到,在2015年没有打印"2015年的时候:小明跟小红在一起"
,因为在这一年他们分手了。
5.4.3 打断指定的循环
使用如下的方式可以打断指定的循环。
例如:
var i, j;
outer: for (i = 0; i < 10; ++i) {
console.info("====");
console.info("i=" + i);
inner: for (j = 0; j < 10; ++j) {
if (j == 3) {
continue inner;
//continue outer;
//break inner;
//break outer;
} c
onsole.log("j=" + j);
}
}
6
数组
数组是值的有序集合。每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引。
JavaScript数组是无类型的:数组元素可以是任意类型 ,并且同一个数组中的不同元素也可能有不同的类型。数组的元素甚至也可能是对象或
其他数组,这允许创建复杂的数据结构,如对象的数组和数组的数组。
JavaScript数组的索引是基于零的32位数值:第一个元素的索引为0 ,最
大可能的索引为
4294967294(232-2),数组最大能容纳29496295 个元素。
JavaScript数组是动态的: 根据需要它们会增长或缩减 ,并且在创建数组时无需声明一个固定的大小或者在数组大小变化时无须重新分配空间。
6.1 定义数组
6.1.1 声明数组
定义一个数组有两种方式:
var arr1 = [];
var arr2 = new Array();
两种均可以声明一个数组,但前者的效率更高,因为前者是使用JSON格式的语法会被JavaScrip
引擎直接解释,而后者则需要调用构造函数。
另外,第一种方式无法为数组指定长度,而第二种可以,例如:
var arr3 = new Array(5);
表示该arr数组的长度是5

其实指不指定长度都无所谓,因为
JavaScript是一门动态语言,即使指定了长度JavaScript 若空间不够的时候,数组的空间也能自动增大。
6.1.2 声明且初始化
我们也可以声明的时候就为数组初始化一些初始化值,例如:
var arr1 = [5, 4, 3, 2, 1];
var arr2 = new Array(5, 4, 3, 2, 1);
这两种方式的效果都一样。
另外,同一个数组可以存储不同类型的数据,可以是基本类型也可以是引用类型,例如:
var arr3 = [true, 2, "a", null, undefined, new Object()];
6.2 读写数组
6.2.1 把数据写入数组
如果想给数组添加元素,可以采取以下的方式:
var arr = ["first"];//数组的长度为 1
arr[1] = "second";//
虽然数组长度是1,但是数组的下标是由0
开始的
var i = 2;
arr[2] = i;//
可以把其他值赋值给数组的元素
var j = 3;
arr[j] = true;//
也可以把变量作为数组下标
另外,在
JavaScript 中数组可以使用负数、非整数来索引数组。在这种情况下,数值会转换为字符串,把字符串作为属性来用。
记住,只有使用
0~232-2 之间的整数下标才是索引,其他均为该数组的属性。
6.2.2 读出数组中的数据
我们可以使用如下方式来根据索引读取数组:
var arr = [5, 4, 3, 2, 1];
var num1 = arr[0];//num1
5
var num2 = arr[1];//num2
4
...
如果是读取数组的属性则可以采取如下方式:
// 赋值方式如下
var arr = [];
arr[name] = "tom";
arr.age = 12;
arr[-1] = true;
//
读取方式如下
console.info(arr.name);//tom
console.info(arr[age]);//
使用点运算符和中括号都一样,但是数字或关键字属性只能使用中括号
console.info(arr["-1"]);//因为负数和非整数会被转换为字符串,或直接使用-1 也行,但是不能使用点运算符
6.3 数组的长度
每个数组都有一个
length属性,就是这个属性使其区别于常规的JavaScript对象。针对稠密(也就是非稀疏)数组,length 属性值代表数组中元素的个
数。其值比数组中最大的索引大
1
例如:
var arr = new Array();
console.info(arr.length);//
数组长度为
0
arr[0] = "123";
console.info(arr[0]);//
数组长度为
1
//
但是上面的索引0明显比数组长度length
1
6.4 数组的遍历
如果我们想把一个数组里面的所有的元素取出来,且这个数组有
10000个元素,可以采取for 循环的方式,例如:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var i;
//i
0开始,因为数组的索引也是从0
开始
for (i = 0; i < arr.length; ++i) {
console.info(arr[i]);//
i
作为数组的索引来取得数组的每一个值
}
6.5 多维数组
多维数组便是数组里面再存入数组。
例如:
// 如下是一个二维数组
var arr = [[true, false], [false, true]];
//
通过索引获取元素
console.info(arr[0]);//获取的是[true, false] 数组
console.info(arr[1]);//获取的是[false, true] 数组
console.info(arr[0][0]);//获取的是第一个数组的第一个元素 true
console.info(arr[0][1]);//
获取的是第一个数组的第二个元素
false
console.info(arr[1][0]);//
获取的是第二个数组的第一个元素
false
console.info(arr[1][1]);//
获取的是第二个数组的第二哥元素
true
一般可以用双重for
循环来获取数组里面的具体值。
例如:
var i, j, arr = [[true, false], [false, true]];
for (i = 0; i < arr.length; ++i) {
for (j = 0; j < arr[i].length; ++j) {
console.info(arr[i][j]);
}
}
6
.6
冒泡排序
冒泡排序的写法:
// 从大到小排列
var arr = [5, 1, 3, 4, 2];
var i, j;
for (i = 0; i < arr.length - 1; ++i) {
for (j = 0; j < arr.length - 1 - j; ++j) {
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
7
函数的简单了解
7.1 函数的定义
7.1.1 命名函数
如果采用如下的方式去定义函数,则称为定义一个命名函数:
function funcName() {
执行语句
...
}
其中,funcName是该函数的名称,因函数Function是属于JavaScript的原生对象,既然是对象则funcName
便是该函数的引用,我们可以使用
funcName来获取该函数的地址,使用funcName()来调用执行它。
7.1.2 匿名函数
另外一种常见的定义函数的方式是匿名函数。
例如:
var funcName = function() {
执行语句
...
}
定义匿名函数与命名函数有点不一样,我们可以看到这个时候function(){}相当于是以直接量的形式把地址赋值给funcName
变量,所以我们可以使用
funcName来获取该函数的地址,使用funcName() 来调用执行它。
7.2 如何使用函数
7.2.1 直接使用
直接使用的意思就是,直接调用来执行一个函数。
例如:
function execute() {
console.info("
正在执行函数!
");
} e
xecute();
如果这样也可以执行哦
~
//
先执行函数,再定义函数
execute();
function execute() {
console.info("
正在执行函数!
");
}
但是使用如下的方式来操作变量会出现问题。
console.info(num);//打印 undefined
var num = 5;
这是因为JavaScript
在执行这些代码的时候会提前把变量包括函数的引用已定义好了(即已添加在全局上下文上了),只是变量还未赋值,但已经可以
调用。
7.2.2 赋值使用
我们可以把函数名作为地址来进行赋值传递。
function func1() {
} v
ar temp = func1;
temp();//
func1()
的执行效果一样
7.3 作用域
7.3.1 普通变量作用域
在一些类似于
C 语言的编程语言,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码之外是不可见的,我们称之为块级作用域
block scope),而JavaScript中没有块级作用域。JavaScript取而代之地使用了函数作用域(function scope) :变量在声明它们的函数体以及这个函数
体嵌套的任意函数体内都是有定义的。
什么意思,先看下代码:

<script type="text/javascript">
var num = 1;
function func() {
console.info(num);//
此处可以打印出正确值,因为num
是全局变量,任何地方都可以使用
var num2 = 5;
} c
onsole.info(num2);//
此处不能正确打印,因为num2只属于func
的函数块作用域
</script>
如上可以看出,定义在函数意外的变量称为全局变量,在任何的函数内都可以调用。
7.3.2 函数变量作用域
我们已经知道,函数的名字可以直接使用作为函数的地址,若打括号表示执行该地址对应的函数,如果没有打括号就仅仅表示地址,即该函数名就是
一个变量,里面的值就是该函数对象的地址。所以,既然是一个地址的变量,并且是变量就有作用域,所以某些存在于具体函数里面的函数不可能达
到在任何地方都可以使用它。
例如:
<script type="text/javascript">
var func1 = function() {
console.info("
执行func1函数
");
var func2 = function() {//--------
标注
3
console.info("
执行func2函数
");
} /
/func2();//
在这里执行func2不会报错--------标注
2
} f
unc1();//
结果:执行func1函数--------标注
1
//func2();//
在这里调用func2
会报错
</script>
在标注1
处的执行结果为:
执行
func1 函数
而不是如下:
执行
func1 函数
执行
func2 函数
这是因为标注
3的代码是属于定义函数,而要执行函数必须把标注2 处的注释解禁。
如上代码也可写作:
<script type="text/javascript">
function func1() {
console.info("
执行func1函数
");
function func2() {
console.info("
执行func2函数
");
} /
/func2();//
在这里执行func2不会报错--------标注
2
} f
unc1();//
结果:执行func1函数--------标注
1
//func2();//
在这里调用func2
会报错
</script>
7.4 传参
7.4.2 参数列表
代码:
var num1 = 1, num2 = 2;
function func(first, second) {//
这里的圆括号内的所有参数的集合称为参数列表,可以传入外部参数到函数中使用
console.info(first);
console.info(second);
} f
unc(num1, num2);
执行结果:
1 2
参数列表可有可无,可以有多个也可以有一个,并且对传入参数的类型不做限制。
7.4.1 形参与实参
请看代码:
var num = 5;
function func(n) {//n
是形参-------标注
1
console.info(n);
} f
unc(num);//
这里的num是实参------标注
2
如上的代码中运行结果为:
5
JavaScript的值传递是属于复制传递,即把num的值复制给n,然后在func的函数体中就可以使用已赋值过的n了。在标注2和标注1
的两个参数是不同的
参数,在不同的内存地址,只是由于
num中的值已经复制给了n所以使用的n的值等同于num 的值。
另外,在该
func 运行完结束后,该函数中的一切变量都会被释放掉,包括这个函数中的任何变量(包括基本类型和引用类型,函数就属于引用类型)。
但是如果出现了如下情况:
var num = 5;
var n = 3;
function func(num) {----------
标注
1
console.info(num);
} f
unc(n);
执行结果:
3
JavaScript有一个作用域链的概念,根据作用域链的原理可知道,如果遇到变量名相同,此时该使用哪一个变量。标注1处的num相当于在函数内
var
num = n;
其中的n就是调用该函数式传入的3,而js
会优先执行该函数内的局部变量,再去执行外部的变量(在这里是全局变量)。
又例如:
var num = 5;
function func() {
var num = 3;
console.info(num);
} f
unc();
执行结果:
3
这个时候,外部的num为全局变量,内部的num
为局部变量,虽然他们名称一样,但是他们的内存空间不冲突,存在于两个不同的地方,但是我们选择
执行哪一个
num的时候,我们会选择最近的局部变量,即函数内部的num
又例如:
var num = 1;
function func(n) {
n = 3;
console.info(n);
} f
unc(num);
console.info(num);
运行结果:
3 1
如果改成如下代码,其运行结果也不会变:
var num = 1;
function func(num) {
num = 3;
console.info(num);
} f
unc(num);
console.info(num);
因为在func内部的num变量与外部的num
根本就不是同一个变量,是两个内存空间的变量,一个是形参,一个是实参,在改变其中一个的值的时候,另
外一个也根本不会受影响。
但是,如果是引用的传递,效果可能会不同哦
~
刚才的所有代码都是使用的值传递,传递的数据都是基本类型,如果传递的数据是属于引用类型,那么会有不同的现象发生,代码如下:
var arr = [1, 2, 3];
function func(a) {//-----------
标注
2
a[0] = 0;
console.info(a);
} f
unc(arr);//----------
标注
1
console.info(arr);
执行结果:
[0, 2, 3]
[0, 2, 3]
为什么两次打印结果一致?不是说函数中的形参跟函数外的形参是两个值吗?
好了,带着这个问题我们来好好分析下。
首先,在标注
1arr采取了引用传递,把地址复制给在标注2a,由于arr是引用类型,所以复制的是一份地址给a,所以aarr 两个引用指向的同一个
对象,那么
a改变了所指向的对象,即使改变了arr 所指向的对象。
7.5 返回值
return可以作为函数的结束语句,只要遇见return那么离return最近的函数就会立即停止执行,并且返回return 后的值。
例如:
function func(n) {
if (n == 1) {

console.info("
传递的值为
1");
return 1;//-------
标注
1
} i
f (n == 2) {
console.info("
传递的值为2");//----标注
2
}
} v
ar num = func(1);
console.info(num);
执行结果:
传递的值为
1
1
因为,return具有结束函数的作用,所以在标注1执行后便会结束,而跳过标注2。另外,num的值取决于函数func中的return
语句后的值,此处
return 1,所以num1
另外,如果没有
return,则numundefined
例如:
function func() {
console.info("
执行函数
");
} v
ar num = func();
console.info(num);
执行结果:
执行函数
undefined
另外,你必须要区分的是,使用匿名函数和获取函数返回值。
例如:
function func1() {
return 1;
} /
/
你需要区分如下三个东西
var num1 = func1();//1 ,值传递
var num2 = func1;// 地址赋值
var func = function() {// 函数的定义
}
1.第一个是地址加上()
,表示执行该地址指向的函数。
2. 第二个只有地址,表示地址的赋值。
3.第三个func是直接接纳的function对象,里面有{}
8 对象的简单了解
8.1 使用类函数(构造函数)创建对象
function Student(name, age) {
this.name = name;
this.age = age;
this.study = function() {
console.info(this.name + "
同学,今年" + this.age + "岁,在朗沃学习前端!
");
}
} v
ar stu = new Student("
张三
", 18);
stu.study();
运行结果:
张三同学,今年
18 岁,在朗沃学习前端!
8.2 使用 JSON 对象
var stu = {
name: "
李思思
",
age: 17,
study: function() {
console.info(this.name + "
同学,芳龄" + this.age + "岁,在朗沃学习UI
");
}
} s
tu.study();
运行结果:
李思思同学,芳龄
17岁,在朗沃学习UI
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值