运算

&&运算是与运算,只有所有都为true&&运算结果才是true

  1. true && true; // 这个&&语句计算结果为true
  2. true && false; // 这个&&语句计算结果为false
  3. false && true && false; // 这个&&语句计算结果为false

||运算是或运算,只要其中有一个为true||运算结果就是true

  1. false || false; // 这个||语句计算结果为false
  2. true || false; // 这个||语句计算结果为true
  3. false || true || false; // 这个||语句计算结果为true

比较

当我们对Number做比较时,可以通过比较运算符得到一个布尔值:

  1. 2 > 5; // false
  2. 5 >= 2; // true
  3. 7 == 7; // true

实际上,JavaScript允许对任意数据类型做比较:

  1. false == 0; // true
  2. false === 0; // false

要特别注意相等运算符==。JavaScript在设计时,有两种比较运算符:

第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;

第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。

由于JavaScript这个设计缺陷,不要使用==比较,始终坚持使用===比较。

另一个例外是NaN这个特殊的Number与所有其他值都不相等,包括它自己:

  1. NaN === NaN; // false

唯一能判断NaN的方法是通过isNaN()函数:

  1. isNaN(NaN); // true

最后要注意浮点数的相等比较:

  1. 1 / 3 === (1 - 2 / 3); // false

这不是JavaScript的设计缺陷。浮点数在运算过程中会产生误差,因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:

  1. Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true

null和undefined

null表示一个“空”的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。

在其他语言中,也有类似JavaScript的null的表示,例如Java也用null,Swift用nil,Python用None表示。但是,在JavaScript中,还有一个和null类似的undefined,它表示“未定义”。

JavaScript的设计者希望用null表示一个空的值,而undefined表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用nullundefined仅仅在判断函数参数是否传递的情况下有用。

另一种创建数组的方法是通过Array()函数实现:

  1. new Array(1, 2, 3); // 创建了数组[1, 2, 3]

对象

JavaScript的对象是一组由键-值组成的无序集合,例如:

  1. var person = {
  2. name: 'Bob',
  3. age: 20,
  4. tags: ['js', 'web', 'mobile'],
  5. city: 'Beijing',
  6. hasCar: true,
  7. zipcode: null
  8. };

JavaScript对象的键都是字符串类型,值可以是任意数据类型。

上述person对象一共定义了6个键值对,其中每个键又称为对象的属性,例如,personname属性为'Bob'zipcode属性为null

要获取一个对象的属性,我们用对象变量.属性名的方式:

  1.  
  1. person.name; // 'Bob'
  2. person.zipcode; // null

strict模式

JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量:

不用var申明的变量会被视为全局变量,为了避免这一缺陷,所有的JavaScript代码都应该使用strict模式。我们在后面编写的JavaScript代码将全部采用strict模式。

数组

JavaScript的Array可以包含任意数据类型,并通过索引来访问每个元素。

请注意,直接给Arraylength赋一个新的值会导致Array大小的变化:

  1. var arr = [1, 2, 3];
  2. arr.length; // 3
  3. arr.length = 6;
  4. arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
  5. arr.length = 2;
  6. arr; // arr变为[1, 2]

请注意,如果通过索引赋值时,索引超过了范围,同样会引起Array大小的变化:

  1. var arr = [1, 2, 3];
  2. arr[5] = 'x';
  3. arr; // arr变为[1, 2, 3, undefined, undefined, 'x']

对象

JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。

JavaScript的对象用于描述现实世界中的某个对象。例如,为了描述“小明”这个淘气的小朋友,我们可以用若干键值对来描述他:

  1. var xiaoming = {
  2. name: '小明',
  3. birth: 1990,
  4. school: 'No.1 Middle School',
  5. height: 1.70,
  6. weight: 65,
  7. score: null
  8. };

最后一个键值对不需要在末尾加,,如果加了,有的浏览器(如低版本的IE)将报错。

访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''括起来:

  1. var xiaohong = {
  2. name: '小红',
  3. 'middle-school': 'No.1 Middle School'
  4. };

xiaohong的属性名middle-school不是一个有效的变量,就需要用''括起来。访问这个属性也无法使用.操作符,必须用['xxx']来访问:

如果访问一个不存在的属性会返回什么呢?JavaScript规定,访问不存在的属性不报错,而是返回undefined

如果我们要检测   xiaoming 是否拥有某一属性,可以用  in 操作符:

  1. var xiaoming = {
  2. name: '小明',
  3. birth: 1990,
  4. school: 'No.1 Middle School',
  5. height: 1.70,
  6. weight: 65,
  7. score: null
  8. };
  9. 'name' in xiaoming; // true
  10. 'grade' in xiaoming; // false

不过要小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的:

  1. 'toString' in xiaoming; // true

因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。

要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

  1. var xiaoming = {
  2. name: '小明'
  3. };
  4. xiaoming.hasOwnProperty('name'); // true
  5. xiaoming.hasOwnProperty('toString'); // false

条件判断

JavaScript把nullundefined0NaN和空字符串''视为false,其他值一概视为true,因此上述代码条件判断的结果是true

循环

  1. var x = 0;
  2. var i;
  3. for (i=1; i<=10000; i++) {
  4. x = x + i;
  5. }
  6. x; // 50005000

让我们来分析一下for循环的控制条件:

  • i=1 这是初始条件,将变量i置为1;
  • i<=10000 这是判断条件,满足时就继续循环,不满足就退出循环;
  • i++ 这是每次循环后的递增条件,由于每次循环后变量i都会加1,因此它终将在若干次循环后不满足判断条件i<=10000而退出循环。

for循环最常用的地方是利用索引来遍历数组:

  1. var arr = ['Apple', 'Google', 'Microsoft'];
  2. var i, x;
  3. for (i=0; i<arr.length; i++) {
  4. x = arr[i];
  5. console.log(x);
  6. }

for循环的3个条件都是可以省略的,如果没有退出循环的判断条件,就必须使用break语句退出循环,否则就是死循环:

  1. var x = 0;
  2. for (;;) { // 将无限循环下去
  3. if (x > 100) {
  4. break; // 通过if判断来退出循环
  5. }
  6. x ++;
  7. }

for ... in

for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:

  1. var o = {
  2. name: 'Jack',
  3. age: 20,
  4. city: 'Beijing'
  5. };
  6. for (var key in o) {
  7. console.log(key); // 'name', 'age', 'city'
  8. }

要过滤掉对象继承的属性,用hasOwnProperty()来实现:

  1. var o = {
  2. name: 'Jack',
  3. age: 20,
  4. city: 'Beijing'
  5. };
  6. for (var key in o) {
  7. if (o.hasOwnProperty(key)) {
  8. console.log(key); // 'name', 'age', 'city'
  9. }
  10. }

由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:

  1. var a = ['A', 'B', 'C'];
  2. for (var i in a) {
  3. console.log(i); // '0', '1', '2'
  4. console.log(a[i]); // 'A', 'B', 'C'

请注意,for ... inArray的循环得到的是String而不是Number

while

for循环在已知循环的初始和结束条件时非常有用。而上述忽略了条件的for循环容易让人看不清循环的逻辑,此时用while循环更佳。

while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:

do ... while

最后一种循环是 do { ... } while() 循环,它和while循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件:

  1. var n = 0;
  2. do {
  3. n = n + 1;
  4. } while (n < 100);
  5. n; // 100

用 do { ... } while() 循环要小心,循环体会至少执行1次,而forwhile循环则可能一次都不执行。

Map和Set

Map是一组键值对的结构,具有极快的查找速度。

举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array

  1. var names = ['Michael', 'Bob', 'Tracy'];
  2. var scores = [95, 75, 85];

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。

如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

  1. var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
  2. m.get('Michael'); // 95

初始化Map需要一个二维数组,或者直接初始化一个空MapMap具有以下方法:

  1. var m = new Map(); // 空Map
  2. m.set('Adam', 67); // 添加新的key-value
  3. m.set('Bob', 59);
  4. m.has('Adam'); // 是否存在key 'Adam': true
  5. m.get('Adam'); // 67
  6. m.delete('Adam'); // 删除key 'Adam'
  7. m.get('Adam'); // undefined

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

  1. var m = new Map();
  2. m.set('Adam', 67);
  3. m.set('Adam', 88);
  4. m.get('Adam'); // 88

Set

SetMap类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set

  1. var s1 = new Set(); // 空Set
  2. var s2 = new Set([1, 2, 3]); // 含1, 2, 3

重复元素在Set中自动被过滤:

  1. var s = new Set([1, 2, 3, 3, '3']);
  2. s; // Set {1, 2, 3, "3"}

通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:

  1. s.add(4);
  2. s; // Set {1, 2, 3, 4}
  3. s.add(4);
  4. s; // 仍然是 Set {1, 2, 3, 4}

通过delete(key)方法可以删除元素:

  1. var s = new Set([1, 2, 3]);
  2. s; // Set {1, 2, 3}
  3. s.delete(3);
  4. s; // Set {1, 2}

MapSet是ES6标准新增的数据类型,请根据浏览器的支持情况决定是否要使用。

iterable

遍历Array可以采用下标循环,遍历MapSet就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,ArrayMapSet都属于iterable类型

具有iterable类型的集合可以通过新的for ... of循环来遍历。

for ... of循环是ES6引入的新的语法

for ... of循环遍历集合,用法如下:

  1. var a = ['A', 'B', 'C'];
  2. var s = new Set(['A', 'B', 'C']);
  3. var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
  4. for (var x of a) { // 遍历Array
  5. console.log(x);
  6. }
  7. for (var x of s) { // 遍历Set
  8. console.log(x);
  9. }
  10. for (var x of m) { // 遍历Map
  11. console.log(x[0] + '=' + x[1]);
  12. }

你可能会有疑问,for ... of循环和for ... in循环有何区别?

for ... in 循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的意外效果:

  1. var a = ['A', 'B', 'C'];
  2. a.name = 'Hello';
  3. for (var x in a) {
  4. console.log(x); // '0', '1', '2', 'name'
  5. }

for ... in循环将把name包括在内,但Arraylength属性却不包括在内。

for ... of循环则完全修复了这些问题,它只循环集合本身的元素:

  1. var a = ['A', 'B', 'C'];
  2. a.name = 'Hello';
  3. for (var x of a) {
  4. console.log(x); // 'A', 'B', 'C'

注意,forEach()方法是ES5.1标准引入的,

你需要测试浏览器是否支持。

SetArray类似,但Set没有索引,因此回调函数的前两个参数都是元素本身:

  1. var s = new Set(['A', 'B', 'C']);
  2. s.forEach(function (element, sameElement, set) {
  3. console.log(element);
  4. });

注意,forEach()方法是ES5.1标准引入的,你需要测试浏览器是否支持。

SetArray类似,但Set没有索引,因此回调函数的前两个参数都是元素本身:

  1. var s = new Set(['A', 'B', 'C']);
  2. s.forEach(function (element, sameElement, set) {
  3. console.log(element);
  4. });

Map的回调函数参数依次为valuekeymap本身:

  1. var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
  2. m.forEach(function (value, key, map) {
  3. console.log(value);
  4. });

如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们。例如,只需要获得Arrayelement

  1. var a = ['A', 'B', 'C'];
  2. a.forEach(function (element) {
  3. console.log(element);
  4. });

1.Javascript 快速入门(主要)的更多相关文章

  1. JavaScript快速入门(四)——JavaScript函数

    函数声明 之前说的三种函数声明中(参见JavaScript快速入门(二)——JavaScript变量),使用Function构造函数的声明方法比较少见,我们暂时不提.function func() { ...

  2. Web开发初探之JavaScript 快速入门

    本文改编和学习自 A JavaScript Primer For Meteor 和 MDN Web教程 前文 Web开发初探 概述 本文以介绍 JavaScript 为主,初学者掌握本文的内容后,将能 ...

  3. javascript快速入门

    这个在w3school在线文档讲解的很详细,还能在线练习. 所以我只写一些入门的东西和最常用的总结以及注意事项: JavaScript 是脚本语言 一般被人们称为JS,Jquery就是对js语言的封装 ...

  4. Javascript快速入门(上篇)

    Javascript的熟练之路,小弟来了. JavaScript简介:JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript ...

  5. Javascript快速入门(下篇)

    Javascript, cheer up. Ajax:其通过在Web页面与服务器之间建立一个额外的处理层,这个处理层就被称为Ajax引擎,它解释来自用户的请求,在后台以异步的方式处理服务器通信,其结构 ...

  6. javascript快速入门21--DOM总结

    跨浏览器开发 市场上的浏览器种类多的不计其数,它们的解释引擎各不相同,期待所有浏览器都一致的支持JavaScript,CSS,DOM,那要等到不知什么时候,然而开发者不能干等着那天.历史上已经有不少方 ...

  7. javascript快速入门10--运算符,语句

    一元运算符 一元运算符只有一个参数,即要操作的对象或值.它们是 ECMAScript 中最简单的运算符. delete 运算符删除对以前定义的对象属性或方法的引用.例如: var obj = new ...

  8. javascript快速入门8--值,类型与类型转换

    原始值和引用值 在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值. 原始值(primitive value)是存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量 ...

  9. javascript快速入门2--变量,小学生数学与简单的交互

    变量 对于变量的理解:变量是数据的代号.如同人的名字一样. var num;//在JavaScript中使用关键字var声明一个变量 在JavaScript中,使用上面的语法,就可以声明一个变量,以便 ...

  10. JavaScript 快速入门回顾

    数据类型Number JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型: 123; // 整数123 0.456; // 浮点数0.456 1.2345e ...

随机推荐

  1. Mysql8.0在windows系统安装一直卡在Starting the server的解决方案

    报错:Beginning configuration step: Starting Server Attempting to start service MySQL80 一直卡在这里,手动启动服务也起 ...

  2. 在uGUI正交相机中实现旋转透视效果

    正常uGUI使用正交相机的话,旋转是没有透视效果的,但如果能实现较简单的透视, 对一些效果表现来说还是不错的:见下图(左为透视效果): 正常思路感觉各种麻烦. 因为uGUI使用unity的x和y方向表 ...

  3. USRP B210 软件定义的无线网络(SDR)支撑设备

    目录 文章目录 目录 蜂窝网络 蜂窝网络的组成 USRP B210 USRP B210 的功能清单与相关参数 USRP B210 的系统结构与运行原理 相关知识储备 SDR RFIC RF 发展历程 ...

  4. 微信小程序订阅消息开发指南(java)

    微信小程序订阅消息开发指南(java) 第一步 准备阶段 1.你得有一个小程序,并且认证了,个人的也行 2.开通订阅消息 小程序后台->功能->订阅消息 3.公共模板库选择一个模板 选择的 ...

  5. Chart.js (v2.9.4)概要介绍

    chart.js是一个非常优秀的开源图表插件,扩展非常灵活,同时也提供了大量的钩子函数,给与用户添加自定义插件,实现个性化的需求. 具体的优势特点,这里不详述,网上大把资料,现开始正式深入了解这个插件 ...

  6. AIRIOT智慧变电站管理解决方案

    随着社会电气化进程的加速,电力需求与日俱增,变电站作为电网的关键节点,其稳定性和智能化管理水平直接关系到整个电力系统的高效运作.传统变电站管理平台难以适应现代电力系统复杂管理需求,存在如下痛点: 数据 ...

  7. Android 13 - Media框架(4)- MediaPlayerService

    关注公众号免费阅读全文,进入音视频开发技术分享群! MediaPlayerService是android的多媒体框架的核心服务之一,该服务存储有android平台所支援的编解码器信息,管理所有通过Me ...

  8. ReplayKit2 有线投屏项目总结

    一.实现目标 iOS11.0以上设备通过USB线连接电脑,在电脑端实时看到手机屏幕内容 画质达到超清720级别,码率可达到1Mbps以上 二.实现技术方案设计 1.手机端采用ReplayKit2框架, ...

  9. 『手撕Vue-CLI』下载指定模板

    开篇 经上篇文章的介绍,实现了获取下载目录地址,接下来实现下载指定模板的功能. 背景 通过很多章节过后,已经可以拿到模板名称,模板版本号,下载目录地址,这些信息都是为了下载指定模板做准备的. 实现 如 ...

  10. 「AntV」X6 自定义vue节点(vue3)

    官方文档 本篇文档只讲解vue3中如何使用,vue2的可以参考下官方文档 安装插件 @antv/x6-vue-shape 添加vue组件 既然使用vue节点,那么我们就需要准备一个vue的组件,这个组 ...