做网站的如何增加电话量,wordpress头部模板,给男票做网站表白的软件,期末网站设计做什么网站比较好大家好#xff0c;小编来为大家解答以下问题#xff0c;电脑浏览器怎么开启javascript#xff0c;浏览器怎么开启javascript支持#xff0c;现在让我们一起来看看吧#xff01; JavaScript历史 要了解JavaScript#xff0c;我们首先要回顾一下JavaScript的诞生。在上个世…大家好小编来为大家解答以下问题电脑浏览器怎么开启javascript浏览器怎么开启javascript支持现在让我们一起来看看吧 JavaScript历史 要了解JavaScript我们首先要回顾一下JavaScript的诞生。在上个世纪的1995年当时的网景公司正凭借其Navigator浏览器成为Web时代开启时最著名的第一代互联网公司GPT改写。由于网景公司希望能在静态HTML页面上添加一些动态效果于是叫Brendan Eich这哥们在两周之内设计出了JavaScript语言。你没看错这哥们只用了10天时间。为什么起名叫JavaScript原因是当时Java语言非常红火所以网景公司希望借Java的名气来推广但事实上JavaScript除了语法上有点像Java其他部分基本上没啥关系。 ECMAScript 因为网景开发了JavaScript一年后微软又模仿JavaScript开发了JScript为了让JavaScript成为全球标准几个公司联合ECMAEuropean Computer Manufacturers Association组织定制了JavaScript语言的标准被称为ECMAScript标准。所以简单说来就是ECMAScript是一种语言标准而JavaScript是网景公司对ECMAScript标准的一种实现。那为什么不直接把JavaScript定为标准呢因为JavaScript是网景的注册商标。不过大多数时候我们还是用JavaScript这个词。如果你遇到ECMAScript这个词简单把它替换为JavaScript就行了。 JavaScript版本 JavaScript语言是在10天时间内设计出来的虽然语言的设计者水平非常NB但谁也架不住“时间紧任务重”所以JavaScript有很多设计缺陷我们后面会慢慢讲到。此外由于JavaScript的标准——ECMAScript在不断发展最新版ECMAScript 6标准简称ES6已经在2015年6月正式发布了所以讲到JavaScript的版本实际上就是说它实现了ECMAScript标准的哪个版本。由于浏览器在发布时就确定了JavaScript的版本加上很多用户还在使用IE6这种古老的浏览器这就导致你在写JavaScript的时候要照顾一下老用户不能一上来就用最新的ES6标准写否则老用户的浏览器是无法运行新版本的JavaScript代码的。不过JavaScript的核心语法并没有多大变化。我们的教程会先讲JavaScript最核心的用法然后针对ES6讲解新增特性。ECMAScript第一版标准发布于1997年 JavaScript基础 快速入门 JavaScript代码可以直接嵌在网页的任何地方不过通常我们都把JavaScript代码放到中 html
headalert(Hello, world);/
/head
body...
/body
/htmlhtml
head src/static/js/abc.js/
/head
body...
/body
/html这样/static/js/abc.js就会被浏览器执行。把JavaScript代码放入一个单独的.js文件中更利于维护代码并且多个页面可以各自引用同一份.js文件。可以在同一个页面中引入多个.js文件还可以在页面中多次编写 js代码… / 浏览器按照顺序依次执行。有些时候你会看到 标签还设置了一个type属性 typetext/java...
/但这是没有必要的因为默认的type就是JavaScript所以不必显式地把type指定为JavaScript。 如何编写JavaScript 我使用的是Visual Studio Code来进行编写 如何运行JavaScript 要让浏览器运行JavaScript必须先有一个HTML页面在HTML页面中引入JavaScript然后让浏览器加载该HTML页面就可以执行JavaScript代码。你也许会想直接在我的硬盘上创建好HTML和JavaScript文件然后用浏览器打开不就可以看到效果了吗这种方式运行部分JavaScript代码没有问题但由于浏览器的安全限制以file://开头的地址无法执行如联网等JavaScript代码最终你还是需要架设一个Web服务器然后以http://开头的地址来正常执行所有JavaScript代码。不过开始学习阶段你无须关心如何搭建开发环境的问题我们提供在页面输入JavaScript代码并直接运行的功能让你专注于JavaScript的学习。 alert(Hello, world); // 观察执行效果浏览器将弹出一个对话框显示“Hello, world”。你也可以修改两个单引号中间的内容再试着运行。 调试 俗话说得好“工欲善其事必先利其器。”写JavaScript的时候如果期望显示ABC结果却显示XYZ到底代码哪里出了问题不要抓狂也不要泄气作为小白要坚信JavaScript本身没有问题浏览器执行也没有问题有问题的一定是我的代码。如何找出问题代码这就需要调试。怎么在浏览器中调试JavaScript代码呢 ① 首先你需要安装Google Chrome浏览器Chrome浏览器对开发者非常友好可以让你方便地调试JavaScript代码。从这里下载Chrome浏览器。打开网页出问题的童鞋请移步国内镜像。② 安装后随便打开一个网页然后点击菜单“查看(View)”-“开发者(Developer)”-“开发者工具(Developer Tools)”浏览器窗口就会一分为二下方就是开发者工具 对于windows系统的快捷键是F12即可直达 解释上述操作先点击“控制台(Console)“在这个面板里可以直接输入JavaScript代码按回车后执行。要查看一个变量的内容在Console中输入console.log(a);回车后显示的值就是变量的内容。关闭Console请点击右上角的“×”按钮。请熟练掌握Console的使用方法在编写JavaScript代码时经常需要在Console运行测试代码。如果你对自己还有更高的要求可以研究开发者工具的“源码(Sources)”掌握断点、单步执行等高级调试技巧。 练习 打开新浪首页然后查看页面源代码找一找引入的JavaScript文件和直接编写在页面中的JavaScript代码。然后在Chrome中打开开发者工具在控制台输入console.log(‘Hello’);回车查看JavaScript代码执行结果。 console.log(Hello)
VM808:1 Hello基本语法 JavaScript的语法和Java语言类似每个语句以;结束语句块用{…}。但是JavaScript并不强制要求在每个语句的结尾加;浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;。让JavaScript引擎自动加分号在某些情况下会改变程序的语义导致运行结果与期望不一致。在本教程中我们不会省略;所有语句都会添加;。最好就是每次自己能够加上分号。例如下面的一行代码就是一个完整的赋值语句 var x 1;下面的一行代码是一个字符串但仍然可以视为一个完整的语句 Hello, world;下面的一行代码包含两个语句每个语句用;表示语句结束 var x 1; var y 2; // 不建议一行写多个语句!我们可以分成多行来进行书写 var x 1;
var y 2;语句块是一组语句的集合例如下面的代码先做了一个判断如果判断成立将执行{…}中的所有语句 if (2 1) {x 1;y 2;z 3;
}注意花括号{…}内的语句具有缩进通常是4个空格。缩进不是JavaScript语法要求必须的但缩进有助于我们理解代码的层次所以编写代码时要遵守缩进规则。很多文本编辑器具有“自动缩进”的功能可以帮助整理代码。{…}还可以嵌套形成层级结构其实这些语句很类似于java都是可以这样进行操作的 if (2 1) {x 1;y 2;z 3;if (x y) {z 4;}if (x y) {z 5;}
}JavaScript本身对嵌套的层级没有限制但是过多的嵌套无疑会大大增加看懂代码的难度。遇到这种情况需要把部分代码抽出来作为函数来调用这样可以减少代码的复杂度。 注释 以//开头直到行末的字符被视为行注释注释是给开发人员看到JavaScript引擎会自动忽略 // 这是一行注释
alert(hello); // 这也是注释另一种块注释是用/…/把多行字符包裹起来把一大“块”视为一个注释 /* 从这里开始是块注释
仍然是注释
仍然是注释
注释结束 */练习 分别利用行注释和块注释把下面的语句注释掉使它不再执行大小写 请注意JavaScript严格区分大小写如果弄错了大小写程序将报错或者运行不正常。 数据类型和变量 数据类型 计算机顾名思义就是可以做数学计算的机器因此计算机程序理所当然地可以处理各种数值。但是计算机能处理的远不止数值还可以处理文本、图形、音频、视频、网页等各种各样的数据不同的数据需要定义不同的数据类型。在JavaScript中定义了以下几种数据类型 Number JavaScript不区分整数和浮点数统一用Number表示以下都是合法的Number类型 123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大当数值超过了JavaScript的Number所能表示的最大值时就表示为Infinity计算机由于使用二进制所以有时候用十六进制表示整数比较方便十六进制用0x前缀和0-9a-f表示例如0xff000xa5b4c3d2等等它们和十进制表示的数值完全一样。Number可以直接做四则运算规则和数学一致 1 2; // 3
(1 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1 注意%是求余运算。
10.5 % 3; // 1.5字符串 字符串是以单引号’或双引号括起来的任意文本比如’abc’“xyz等等。请注意’或”本身只是一种表示方式不是字符串的一部分因此字符串’abc’只有abc这3个字符。 布尔值布尔值和布尔代数的表示完全一致一个布尔值只有true、false两种值要么是true要么是false可以直接用true、false表示布尔值也可以通过布尔运算计算出来 true; // 这是一个true值
false; // 这是一个false值
2 1; // 这是一个true值
2 3; // 这是一个false值运算是与运算只有所有都为true运算结果才是true true true; // 这个语句计算结果为true
true false; // 这个语句计算结果为false
false true false; // 这个语句计算结果为false||运算是或运算只要其中有一个为true||运算结果就是true false || false; // 这个||语句计算结果为false
true || false; // 这个||语句计算结果为true
false || true || false; // 这个||语句计算结果为true!运算是非运算它是一个单目运算符把true变成falsefalse变成true ! true; // 结果为false
! false; // 结果为true
! (2 5); // 结果为true布尔值经常用在条件判断中比如 var age 15;
if (age 18) {alert(adult);
} else {alert(teenager);
}比较运算符 当我们对Number做比较时可以通过比较运算符得到一个布尔值 2 5; // false
5 2; // true
7 7; // true实际上JavaScript允许对任意数据类型做比较 false 0; // true
false 0; // false要特别注意相等运算符。JavaScript在设计时有两种比较运算符第一种是比较它会自动转换数据类型再比较很多时候会得到非常诡异的结果第二种是比较它不会自动转换数据类型如果数据类型不一致返回false如果一致再比较。由于JavaScript这个设计缺陷不要使用比较始终坚持使用比较。另一个例外是NaN这个特殊的Number与所有其他值都不相等包括它自己 NaN NaN; // fals唯一能判断NaN的方法是通过isNaN()函数 isNaN(NaN); // true最后要注意浮点数的相等比较 1 / 3 (1 - 2 / 3); // false这不是JavaScript的设计缺陷。浮点数在运算过程中会产生误差因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等只能计算它们之差的绝对值看是否小于某个阈值 Math.abs(1 / 3 - (1 - 2 / 3)) 0.0000001; // truenull和undefined null表示一个“空”的值它和0以及空字符串’‘不同0是一个数值’表示长度为0的字符串而null表示“空”。在其他语言中也有类似JavaScript的null的表示例如Java也用nullSwift用nilPython用None表示。但是在JavaScript中还有一个和null类似的undefined它表示“未定义”。JavaScript的设计者希望用null表示一个空的值而undefined表示值未定义。事实证明这并没有什么卵用区分两者的意义不大。大多数情况下我们都应该用null。undefined仅仅在判断函数参数是否传递的情况下有用。 数组 数组是一组按顺序排列的集合集合的每个值称为元素。**JavaScript的数组可以包括任意数据类型。**例如 [1, 2, 3.14, Hello, null, true];上述数组包含6个元素。数组用[]表示元素之间用,分隔。另一种创建数组的方法是通过Array()函数实现 new Array(1, 2, 3); // 创建了数组[1, 2, 3]然而出于代码的可读性考虑强烈建议直接使用[]。数组的元素可以通过索引来访问。请注意索引的起始值为0 var arr [1, 2, 3.14, Hello, null, true];
arr[0]; // 返回索引为0的元素即1
arr[5]; // 返回索引为5的元素即true
arr[6]; // 索引超出了范围返回undefined对象 JavaScript的对象是一组由键-值组成的无序集合例如 var person {name: Bob,age: 20,tags: [js, web, mobile],city: Beijing,hasCar: true,zipcode: null
};JavaScript对象的键都是字符串类型值可以是任意数据类型。上述person对象一共定义了6个键值对其中每个键又称为对象的属性例如person的name属性为’Bob’zipcode属性为null。 要获取一个对象的属性我们用对象变量.属性名的方式 person.name; // Bob
person.zipcode; // null变量 变量的概念基本上和初中代数的方程变量是一致的只是在计算机程序中变量不仅可以是数字还可以是任意数据类型。变量在JavaScript中就是用一个变量名表示变量名是大小写英文、数字、$和_的组合且不能用数字开头。变量名也不能是JavaScript的关键字如if、while等。申明一个变量用var语句比如 var a; // 申明了变量a此时a的值为undefined
var $b 1; // 申明了变量$b同时给$b赋值此时$b的值为1
var s_007 007; // s_007是一个字符串
var Answer true; // Answer是一个布尔值true
var t null; // t的值是null变量名也可以用中文但是请不要给自己找麻烦最好不要使用。在JavaScript中使用等号对变量进行赋值。可以把任意数据类型赋值给变量同一个变量可以反复赋值而且可以是不同类型的变量但是要注意只能用var申明一次例如 var a 123; // a的值是整数123
a ABC; // a变为字符串这种变量本身类型不固定的语言称之为动态语言与之对应的是静态语言。静态语言在定义变量时必须指定变量类型如果赋值的时候类型不匹配就会报错。例如Java是静态语言赋值语句如下 int a 123; // a是整数类型变量类型用int申明
a ABC; // 错误不能把字符串赋给整型变量和静态语言相比动态语言更灵活就是这个原因。请不要把赋值语句的等号等同于数学的等号。比如下面的代码 var x 10;
x x 2;如果从数学上理解x x 2那无论如何是不成立的在程序中赋值语句先计算右侧的表达式x 2得到结果12再赋给变量x。由于x之前的值是10重新赋值后x的值变成12要显示变量的内容可以用console.log(x)打开Chrome的控制台就可以看到结果。 // 打印变量x
var x 100;
console.log(x);
// 测试
100使用console.log()代替alert()的好处是可以避免弹出烦人的对话框。 strict模式 JavaScript在设计之初为了方便初学者学习并不强制要求用var申明变量。这个设计错误带来了严重的后果如果一个变量没有通过var申明就被使用那么该变量就自动被申明为全局变量 i 10; // i现在是全局变量在同一个页面的不同的JavaScript文件中如果都不用var申明恰好都使用了变量i将造成变量i互相影响产生难以调试的错误结果。使用var申明的变量则不是全局变量它的范围被限制在该变量被申明的函数体内函数的概念将稍后讲解同名变量在不同的函数体内互不冲突。为了修补JavaScript这一严重设计缺陷ECMA在后续规范中推出了strict模式在strict模式下运行的JavaScript代码强制通过var申明变量未使用var申明变量就使用的将导致运行错误。启用strict模式的方法是在JavaScript代码的第一行写上 use strict;这是一个字符串不支持strict模式的浏览器会把它当做一个字符串语句执行支持strict模式的浏览器将开启strict模式运行JavaScript。不用var申明的变量会被视为全局变量为了避免这一缺陷所有的JavaScript代码都应该使用strict模式。我们在后面编写的JavaScript代码将全部采用strict模式。 字符串 JavaScript的字符串就是用’ 或 括起来的字符表示。如果’本身也是一个字符那就可以用 括起来比如I’m OK包含的字符是I’m空格OK这6个字符。如果字符串内部既包含’又包含怎么办可以用转义字符\来标识比如 I\m \OK\!;表示的字符串内容是I’m “OK”!转义字符\可以转义很多字符比如\n表示换行\t表示制表符字符\本身也要转义所以\表示的字符就是\。ASCII字符可以以\x##形式的十六进制表示例如 \x41; // 完全等同于 A还可以用\u####表示一个Unicode字符 \u4e2d\u6587; // 完全等同于 中文多行字符串 由于多行字符串用\n写起来比较费事所以最新的ES6标准新增了一种多行字符串的表示方法用反引号...表示 这是一个
多行
字符串;注意反引号在键盘的ESC下方数字键1的左边练习测试你的浏览器是否支持ES6标准如果不支持请把多行字符串用\n重新表示出来模板字符串要把多个字符串连接起来可以用 号连接 var name 小明;
var age 20;
var message 你好, name , 你今年 age 岁了!;
alert(message);如果有很多变量需要连接用号就比较麻烦。ES6新增了一种模板字符串表示方法和上面的多行字符串一样但是它会自动替换字符串中的变量 var name 小明;
var age 20;
var message 你好, ${name}, 你今年${age}岁了!;
alert(message);练习测试你的浏览器是否支持ES6模板字符串如果不支持请把模板字符串改为连接的普通字符串操作字符串字符串常见的操作如下 var s Hello, world!;
s.length; // 13要获取字符串某个指定位置的字符使用类似Array的下标操作索引号从0开始索引都是从0开始的 var s Hello, world!;s[0]; // H
s[6]; //
s[7]; // w
s[12]; // !
s[13]; // undefined 超出范围的索引不会报错但一律返回undefined需要特别注意的是字符串是不可变的如果对字符串的某个索引赋值不会有任何错误但是也没有任何效果 var s Test;
s[0] X;
alert(s); // s仍然为TestJavaScript为字符串提供了一些常用方法注意调用这些方法本身不会改变原有字符串的内容而是返回一个新字符串 toUpperCase toUpperCase()把一个字符串全部变为大写 var s Hello;
s.toUpperCase(); // 返回HELLOtoLowerCase toLowerCase()把一个字符串全部变为小写 var s Hello;
var lower s.toLowerCase(); // 返回hello并赋值给变量lower
lower; // helloindexOf indexOf()会搜索指定字符串出现的位置 var s hello, world;
s.indexOf(world); // 返回7返回第一个出现的位置
s.indexOf(World); // 没有找到指定的子串返回-1substring substring()返回指定索引区间的子串 var s hello, world
s.substring(0, 5); // 从索引0开始到5不包括5返回hello
s.substring(7); // 从索引7开始到结束返回world数组 JavaScript的Array可以包含任意数据类型并通过索引来访问每个元素。要取得Array的长度直接访问length属性 [ … ] var arr [1, 2, 3.14, Hello, null, true];
arr.length; // 6请注意直接给Array的length赋一个新的值会导致Array大小的变化 var arr [1, 2, 3];
arr.length; // 3
arr.length 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length 2;
arr; // arr变为[1, 2]Array可以通过索引把对应的元素修改为新的值因此对Array的索引进行赋值会直接修改这个Array var arr [A, B, C];
arr[1] 99;
arr; // arr现在变为[A, 99, C]请注意如果通过索引赋值时索引超过了范围同样会引起Array大小的变化 var arr [1, 2, 3];
arr[5] x;
arr; // arr变为[1, 2, 3, undefined, undefined, x]大多数其他编程语言不允许直接改变数组的大小越界访问索引会报错。然而JavaScript的Array却不会有任何错误。在编写代码时不建议直接修改Array的大小访问索引时要确保索引不会越界。-- javaScript比较宽松 indexOf 与String类似Array也可以通过**indexOf()**来搜索一个指定的元素的位置通过一个方法来进行指定 var arr [10, 20, 30, xyz];
arr.indexOf(10); // 元素10的索引为0
arr.indexOf(20); // 元素20的索引为1
arr.indexOf(30); // 元素30没有找到返回-1
arr.indexOf(30); // 元素30的索引为2注意了数字30和字符串’30’是不同的元素。 slice slice()就是对应String的substring()版本它截取Array的部分元素然后返回一个新的Array var arr [A, B, C, D, E, F, G];
arr.slice(0, 3); // 从索引0开始到索引3结束但不包括索引3: [A, B, C]
arr.slice(3); // 从索引3开始到结束: [D, E, F, G]注意到slice()的起止参数包括开始索引不包括结束索引。 var arr [A, B, C, D, E, F, G];
var aCopy arr.slice();
aCopy; // [A, B, C, D, E, F, G]
aCopy arr; // falsepush和pop – 对数组末尾进行相应操作 push()向Array的末尾添加若干元素pop()则把Array的最后一个元素删除掉 var arr [1, 2];
arr.push(A, B); // 返回Array新的长度: 4
arr; // [1, 2, A, B]
arr.pop(); // pop()返回B
arr; // [1, 2, A]
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错而是返回undefined
arr; // []unshift和shift 如果要往Array的头部添加若干元素使用unshift()方法shift()方法则把Array的第一个元素删掉 var arr [1, 2];
arr.unshift(A, B); // 返回Array新的长度: 4
arr; // [A, B, 1, 2]
arr.shift(); // A
arr; // [B, 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错而是返回undefined
arr; // []sort sort()可以对当前Array进行排序它会直接修改当前Array的元素位置直接调用时按照默认顺序排序 var arr [B, C, A];
arr.sort();
arr; // [A, B, C]能否按照我们自己指定的顺序排序呢完全可以我们将在后面的函数中讲到。 reverse reverse()把整个Array的元素给调个个也就是反转 var arr [one, two, three];
arr.reverse();
arr; // [three, two, one]splice splice()方法是修改Array的“万能方法”它可以从指定的索引开始删除若干元素然后再从该位置添加若干元素 var arr [Microsoft, Apple, Yahoo, AOL, Excite, Oracle];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, Google, Facebook); // 返回删除的元素 [Yahoo, AOL, Excite]
arr; // [Microsoft, Apple, Google, Facebook, Oracle]
// 只删除,不添加:
arr.splice(2, 2); // [Google, Facebook]
arr; // [Microsoft, Apple, Oracle]
// 只添加,不删除:
arr.splice(2, 0, Google, Facebook); // 返回[],因为没有删除任何元素
arr; // [Microsoft, Apple, Google, Facebook, Oracle]concat concat()方法把当前的Array和另一个Array连接起来并返回一个新的Array var arr [A, B, C];
var added arr.concat([1, 2, 3]);
added; // [A, B, C, 1, 2, 3]
arr; // [A, B, C]请注意concat()方法并没有修改当前Array而是返回了一个新的Array。实际上concat()方法可以接收任意个元素和Array并且自动把Array拆开然后全部添加到新的Array里 var arr [A, B, C];
arr.concat(1, 2, [3, 4]); // [A, B, C, 1, 2, 3, 4]join join()方法是一个非常实用的方法它把当前Array的每个元素都用指定的字符串连接起来然后返回连接后的字符串 var arr [A, B, C, 1, 2, 3];
arr.join(-); // A-B-C-1-2-3如果Array的元素不是字符串将自动转换为字符串后再连接。 多维数组 如果数组的某个元素又是一个Array则可以形成多维数组例如 var arr [[1, 2, 3], [400, 500, 600], -];练习1 如何通过索引取到500这个值练习2 在新生欢迎会上你已经拿到了新同学的名单请排序后显示欢迎XXXXXXXXX和XXX同学小总结Array提供了一种顺序存储一组元素的功能并可以按索引来读写。 对象 JavaScript的对象是一种无序的集合数据类型它由若干键值对组成。JavaScript的对象用于描述现实世界中的某个对象。例如为了描述“小明”这个淘气的小朋友我们可以用若干键值对来描述他 var xiaoming {name: 小明,birth: 1990,school: No.1 Middle School,height: 1.70,weight: 65,score: null
};JavaScript用一个{…}表示一个对象键值对以xxx: xxx形式申明用,隔开。注意最后一个键值对不需要在末尾加,如果加了有的浏览器如低版本的IE将报错。上述对象申明了一个name属性值是’小明’birth属性值是1990以及其他一些属性。最后把这个对象赋值给变量xiaoming后就可以通过变量xiaoming来获取小明的属性了 xiaoming.name; // 小明
xiaoming.birth; // 1990通过的是对象名.属性的形式来进行 访问属性是通过.操作符完成的但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符就必须用’括起来 var xiaohong {name: 小红,middle-school: No.1 Middle School
};xiaohong的属性名middle-school不是一个有效的变量就需要用’括起来。访问这个属性也无法使用.操作符必须用[‘xxx’]来访问 xiaohong[middle-school]; // No.1 Middle School
xiaohong[name]; // 小红
xiaohong.name; // 小红也可以用xiaohong[‘name’]来访问xiaohong的name属性不过xiaohong.name的写法更简洁。我们在编写JavaScript代码的时候属性名尽量使用标准的变量名这样就可以直接通过object.prop的形式访问一个属性了。实际上JavaScript对象的所有属性都是字符串不过属性对应的值可以是任意数据类型。如果访问一个不存在的属性会返回什么呢JavaScript规定访问不存在的属性不报错而是返回undefined – 未定义的由于JavaScript的对象是动态类型你可以自由地给一个对象添加或删除属性 var xiaoming {name: 小明
};
xiaoming.age; // undefined
xiaoming.age 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined
delete xiaoming[name]; // 删除name属性
xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错如果我们要检测xiaoming是否拥有某一属性可以用in操作符 – 是否存在其中 var xiaoming {name: 小明,birth: 1990,school: No.1 Middle School,height: 1.70,weight: 65,score: null
};
name in xiaoming; // true
grade in xiaoming; // false不过要小心如果in判断一个属性存在这个属性不一定是xiaoming的它可能是xiaoming继承得到的 toString in xiaoming; // true因为toString定义在object对象中而所有对象最终都会在原型链上指向object所以xiaoming也拥有toString属性。要判断一个属性是否是xiaoming自身拥有的而不是继承得到的可以用hasOwnProperty()方法 var xiaoming {name: 小明
};
xiaoming.hasOwnProperty(name); // true
xiaoming.hasOwnProperty(toString); // false条件判断 JavaScript使用if () { … } else { … }来进行条件判断。例如根据年龄显示不同内容可以用if语句实现如下 – 和Java的条件判断是类似的这一点还是很关键的 var age 20;
if (age 18) { // 如果age 18为true则执行if语句块alert(adult);
} else { // 否则执行else语句块alert(teenager);
}其中else语句是可选的。如果语句块只包含一条语句那么可以省略{} var age 20;
if (age 18)alert(adult);
elsealert(teenager);省略{}的危险之处在于如果后来想添加一些语句却忘了写{}就改变了if…else…的语义例如 var age 20;
if (age 18)alert(adult);
elseconsole.log(age 18); // 添加一行日志alert(teenager); // - 这行语句已经不在else的控制范围了上述代码的else子句实际上只负责执行console.log(‘age 18’);原有的alert(‘teenager’);已经不属于if…else…的控制范围了它每次都会执行。-- 所以总结一点就是在书写if … else的时候最好是每次加上 {}相反地有{}的语句就不会出错 var age 20;
if (age 18) {alert(adult);
} else {console.log(age 18);alert(teenager);
}这就是为什么我们建议永远都要写上{}。 多行条件判断 如果还要更细致地判断条件可以使用多个if…else…的组合 var age 3;
if (age 18) {alert(adult);
} else if (age 6) {alert(teenager);
} else {alert(kid);
}上述多个if…else…的组合实际上相当于两层if…else…相当于两层 var age 3;
if (age 18) {alert(adult);
} else {if (age 6) {alert(teenager);} else {alert(kid);}
}但是我们通常把else if连写在一起来增加可读性。这里的else略掉了{}是没有问题的因为它只包含一个if语句。注意最后一个单独的else不要略掉{}。 请注意if…else…语句的执行特点是二选一在多个if…else…语句中如果某个条件成立则后续就不再继续判断了。 试解释为什么下面的代码显示的是teenager 由于age的值为20它实际上同时满足条件age 6和age 18这说明**条件判断的顺序非常重要。**请修复后让其显示adult。 如果if的条件判断语句结果不是true或false怎么办例如 var s 123;
if (s.length) { // 条件计算结果为3//
}JavaScript把null、undefined、0、NaN和空字符串’视为false其他值一概视为true因此上述代码条件判断的结果是true。 练习 JavaScript中的打印使用的是 console.log() 循环 要计算123我们可以直接写表达式 1 2 3; // 6要计算123…10勉强也能写出来。但是要计算123…10000直接写表达式就不可能了。为了让计算机能计算成千上万次的重复运算我们就需要循环语句。JavaScript的循环有两种一种是for循环通过初始条件、结束条件和递增条件来循环执行语句块-- 这个和java的for循环也是类似的 var x 0;
var i;
for (i1; i10000; i) {x x i;
}
x; // 50005000让我们来分析一下for循环的控制条件 i1 这是初始条件将变量i置为1i10000 这是判断条件满足时就继续循环不满足就退出循环i 这是每次循环后的递增条件由于每次循环后变量i都会加1因此它终将在若干次循环后不满足判断条件i10000而退出循环。 练习 利用for循环计算1 * 2 * 3 * … * 10的结果 JavaScript中的for循环中i不需要定义相应的类型for循环最常用的地方是利用索引来遍历数组 var arr [Apple, Google, Microsoft];
var i, x;
for (i0; iarr.length; i) {x arr[i];console.log(x);
}和python一开始不同就是其需要定义相应的类型变量来进行接收for循环的3个条件都是可以省略的如果没有退出循环的判断条件就必须使用break语句退出循环否则就是死循环 var x 0;
for (;;) { // 将无限循环下去if (x 100) {break; // 通过if判断来退出循环}x ;
}for … in for循环的一个变体是for … in循环它可以把一个对象的所有属性依次循环出来 var o {name: Jack,age: 20,city: Beijing
};
for (var key in o) {console.log(key); // name, age, city
}要过滤掉对象继承的属性用hasOwnProperty()来实现 var o {name: Jack,age: 20,city: Beijing
};
for (var key in o) {if (o.hasOwnProperty(key)) {console.log(key); // name, age, city}
}由于Array也是对象而它的每个元素的索引被视为对象的属性因此for … in循环可以直接循环出Array的索引 var a [A, B, C];
for (var i in a) {console.log(i); // 0, 1, 2console.log(a[i]); // A, B, C
}请注意for … in对Array的循环得到的是String而不是Number。 while for循环在已知循环的初始和结束条件时非常有用。而上述忽略了条件的for循环容易让人看不清循环的逻辑此时用while循环更佳。while循环只有一个判断条件条件满足就不断循环条件不满足时则退出循环。比如我们要计算100以内所有奇数之和可以用while循环实现 var x 0;
var n 99;
while (n 0) {x x n;n n - 2;
}
x; // 2500在循环内部变量n不断自减直到变为-1时不再满足while条件循环退出。 do … while 最后一种循环是do { … } while()循环它和while循环的唯一区别在于不是在每次循环开始的时候判断条件而是在每次循环完成的时候判断条件 var n 0;
do {n n 1;
} while (n 100);
n; // 100用do { … } while()循环要小心循环体会至少执行1次而for和while循环则可能一次都不执行。 练习 请利用循环遍历数组中的每个名字并显示Hello, xxx!练习plus: 请尝试for循环和while循环并以正序、倒序两种方式遍历。正序倒序小总结 循环是让计算机做重复任务的有效的方法有些时候如果代码写得有问题会让程序陷入“死循环”也就是永远循环下去。JavaScript的死循环会让浏览器无法正常显示或执行当前页面的逻辑有的浏览器会直接挂掉有的浏览器会在一段时间后提示你强行终止JavaScript的执行因此要特别注意死循环的问题。在编写循环代码时务必小心编写初始条件和判断条件尤其是边界值。特别注意i 100和i 100是不同的判断逻辑。 Map和Set JavaScript的默认对象表示方式{}可以视为其他语言中的Map或Dictionary的数据结构即一组键值对。但是JavaScript的对象有个小问题就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。为了解决这个问题最新的ES6规范引入了新的数据类型Map。要测试你的浏览器是否支持ES6规范请执行以下代码如果浏览器报ReferenceError错误那么你需要换一个支持ES6的浏览器-- 现在一般的浏览器都是支持deMapMap是一组键值对的结构具有极快的查找速度。举个例子假设要根据同学的名字查找对应的成绩如果用Array实现需要两个Array var names [Michael, Bob, Tracy];
var scores [95, 75, 85];给定一个名字要查找对应的成绩就先要在names中找到对应的位置再从scores取出对应的成绩Array越长耗时越长。如果用Map实现只需要一个“名字”-“成绩”的对照表直接根据名字查找成绩无论这个表有多大查找速度都不会变慢。用JavaScript写一个Map如下直接使用new Map() var m new Map([[Michael, 95], [Bob, 75], [Tracy, 85]]);
m.get(Michael); // 95初始化Map需要一个二维数组或者直接初始化一个空Map。Map具有以下方法 var m new Map(); // 空Map
m.set(Adam, 67); // 添加新的key-value
m.set(Bob, 59);
m.has(Adam); // 是否存在key Adam: true
m.get(Adam); // 67
m.delete(Adam); // 删除key Adam
m.get(Adam); // undefined由于一个key只能对应一个value所以多次对一个key放入value后面的值会把前面的值冲掉 var m new Map();
m.set(Adam, 67);
m.set(Adam, 88);
m.get(Adam); // 88Set Set和Map类似也是一组key的集合但不存储value。由于key不能重复所以在Set中没有重复的key。要创建一个Set需要提供一个Array作为输入或者直接创建一个空Set var s1 new Set(); // 空Set
var s2 new Set([1, 2, 3]); // 含1, 2, 3重复元素在Set中自动被过滤 var s new Set([1, 2, 3, 3, 3]);
s; // Set {1, 2, 3, 3}注意数字3和字符串’3’是不同的元素。通过**add(key)**方法可以添加元素到Set中可以重复添加但不会有效果 s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}通过delete(key)方法可以删除元素 var s new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
小结Map和Set是ES6标准新增的数据类型请根据浏览器的支持情况决定是否要使用。 迭代器 – iterable 遍历Array可以采用下标循环遍历Map和Set就无法使用下标。为了统一集合类型ES6标准引入了新的iterable类型Array、Map和Set都属于iterable类型。具有iterable类型的集合可以通过新的for … of循环来遍历。for … of循环是ES6引入的新的语法请测试你的浏览器是否支持用for … of循环遍历集合用法如下遍历的时候变量前面具体什么类型是需要说明清楚的 var a [A, B, C];
var s new Set([A, B, C]);
var m new Map([[1, x], [2, y], [3, z]]);
for (var x of a) { // 遍历Arrayconsole.log(x);
}
for (var x of s) { // 遍历Setconsole.log(x);
}
for (var x of m) { // 遍历Mapconsole.log(x[0] x[1]);
}你可能会有疑问for … of循环和for … in循环有何区别for … in循环由于历史遗留问题它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象它的每个元素的索引被视为一个属性。当我们手动给Array对象添加了额外的属性后for … in循环将带来意想不到的意外效果 var a [A, B, C];
a.name Hello;
for (var x in a) {console.log(x); // 0, 1, 2, name
}for … in循环将把name包括在内但Array的length属性却不包括在内。for … of循环则完全修复了这些问题它只循环集合本身的元素 var a [A, B, C];
a.name Hello;
for (var x of a) {console.log(x); // A, B, C
}这就是为什么要引入新的for … of循环。然而更好的方式是直接使用iterable内置的forEach方法它接收一个函数每次迭代就自动回调该函数。以Array为例注意forEach()方法是ES5.1标准引入的你需要测试浏览器是否支持。Set与Array类似但Set没有索引因此回调函数的前两个参数都是元素本身 var s new Set([A, B, C]);
s.forEach(function (element, sameElement, set) {console.log(element);
});Map的回调函数参数依次为value、key和map本身 var m new Map([[1, x], [2, y], [3, z]]);
m.forEach(function (value, key, map) {console.log(value);
});如果对某些参数不感兴趣由于JavaScript的函数调用不要求参数必须一致因此可以忽略它们。例如只需要获得Array的element var a [A, B, C];
a.forEach(function (element) {console.log(element);
});函数 函数定义和调用 定义函数 在JavaScript中定义函数的方式如下 function abs(x) {if (x 0) {return x;} else {return -x;}
}上述函数abs() 函数的定义如下 function指出这是一个函数定义abs是函数的名称(x)括号内列出函数的参数多个参数以,分隔{ … }之间的代码是函数体可以包含若干语句甚至可以没有任何语句。、 请注意函数体内部的语句在执行时一旦执行到return时函数就执行完毕并将结果返回。因此函数内部通过条件判断和循环可以实现非常复杂的逻辑。 如果没有return语句函数执行完毕后也会返回结果只是结果为undefined。 由于JavaScript的函数也是一个对象上述定义的abs()函数实际上是一个函数对象而函数名abs可以视为指向该函数的变量。非常的关键就是如此。 因此第二种定义函数的方式如下-- 通过一个变量来进行接收 var abs function (x) {if (x 0) {return x;} else {return -x;}
};在这种方式下function (x) { … }是一个匿名函数它没有函数名。但是这个匿名函数赋值给了变量abs所以通过变量abs就可以调用该函数。上述两种定义完全等价注意第二种方式按照完整语法需要在函数体末尾加一个;表示赋值语句结束。-- 按照相应的语法来进行操作即可 调用函数 调用函数时按顺序传入参数即可 abs(10); // 返回10
abs(-9); // 返回9由于JavaScript允许传入任意个参数而不影响调用因此传入的参数比定义的参数多也没有问题虽然函数内部并不需要这些参数 abs(10, blablabla); // 返回10
abs(-9, haha, hehe, null); // 返回9传入的参数比定义的少也没有问题 abs(); // 返回NaN此时abs(x)函数的参数x将收到undefined计算结果为NaN。要避免收到undefined可以对参数进行检查 function abs(x) {if (typeof x ! number) {throw Not a number;}if (x 0) {return x;} else {return -x;}
}arguments – 类似于一个Array但不是一个Array。 JavaScript还有一个免费赠送的关键字arguments它只在函数内部起作用并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array function foo(x) {console.log(x x); // 10for (var i0; iarguments.length; i) {console.log(arg i arguments[i]); // 10, 20, 30}
}
foo(10, 20, 30);
// 运行
x 10
arg 0 10
arg 1 20
arg 2 30利用arguments你可以获得调用者传入的所有参数。也就是说即使函数不定义任何参数还是可以拿到参数的值 function abs() {if (arguments.length 0) {return 0;}var x arguments[0];return x 0 ? x : -x;
}
// 测试
abs(); // 0
abs(10); // 10
abs(-9); // 9利用arguments你可以获得调用者传入的所有参数。也就是说即使函数不定义任何参数还是可以拿到参数的值 function abs() {if (arguments.length 0) {return 0;}var x arguments[0];return x 0 ? x : -x;
}
// 测试
abs(); // 0
abs(10); // 10
abs(-9); // 9实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法 // foo(a[, b], c)
// 接收2~3个参数b是可选参数如果只传2个参数b默认为null
function foo(a, b, c) {if (arguments.length 2) {// 实际拿到的参数是a和bc为undefinedc b; // 把b赋给cb null; // b变为默认值重新进行赋值默认值就是null}// ...
}要把中间的参数b变为“可选”参数就只能通过arguments判断然后重新调整参数并赋值。 rest参数 由于JavaScript函数允许接收任意个参数于是我们就不得不用arguments来获取所有参数 function foo(a, b) {var i, rest [];if (arguments.length 2) {for (i 2; iarguments.length; i) {rest.push(arguments[i]);}}console.log(a a);console.log(b b);console.log(rest);
}为了获取除了已定义参数a、b之外的参数我们不得不用arguments并且循环要从索引2开始以便排除前两个参数这种写法很别扭只是为了获得额外的rest参数有没有更好的方法ES6标准引入了rest参数上面的函数可以改写为 function foo(a, b, ...rest) {console.log(a a);console.log(b b);console.log(rest);
}foo(1, 2, 3, 4, 5);
// 结果:
// a 1
// b 2
// Array [ 3, 4, 5 ]foo(1);
// 结果:
// a 1
// b undefined
// Array []rest参数只能写在最后前面用…标识从运行结果可知传入的参数先绑定a、b多余的参数以数组形式交给变量rest所以不再需要arguments我们就获取了全部参数。 – 多余的参数才是会给到变量rest因为rest参数是ES6新标准所以你需要测试一下浏览器是否支持。请用rest参数编写一个sum()函数接收任意个参数并返回它们的和小心你的return语句前面我们讲到了JavaScript引擎有一个在行末自动添加分号的机制这可能让你栽到return语句的一个大坑 function foo() {return { name: foo };
}foo(); // { name: foo }如果把return语句拆成两行 function foo() {return{ name: foo };
}foo(); // undefined要小心了由于JavaScript引擎在行末自动添加分号的机制上面的代码实际上变成了 – 引擎会在行末自动添加分号机制 function foo() {return; // 自动添加了分号相当于return undefined;{ name: foo }; // 这行语句已经没法执行到了
}所以正确的多行写法是 function foo() {return { // 这里不会自动加分号因为{表示语句尚未结束name: foo};
}练习 一定义一个计算圆面积的函数area_of_circle()它有两个参数 r: 表示圆的半径pi: 表示π的值如果不传则默认3.14 // 需要一个简单的判断来知道pi的值到底是用什么才合适。小明是一个JavaScript新手他写了一个max()函数返回两个数中较大的那个JavaScript编译器会自动在每一句代码结束以后自动添加分号