1.Javascript 快速入门(主要)
运算
&&
运算是与运算,只有所有都为true
,&&
运算结果才是true
:
- true && true; // 这个&&语句计算结果为true
- true && false; // 这个&&语句计算结果为false
- false && true && false; // 这个&&语句计算结果为false
||
运算是或运算,只要其中有一个为true
,||
运算结果就是true
:
- false || false; // 这个||语句计算结果为false
- true || false; // 这个||语句计算结果为true
- false || true || false; // 这个||语句计算结果为true
比较
当我们对Number做比较时,可以通过比较运算符得到一个布尔值:
- 2 > 5; // false
- 5 >= 2; // true
- 7 == 7; // true
实际上,JavaScript允许对任意数据类型做比较:
- false == 0; // true
- false === 0; // false
要特别注意相等运算符==
。JavaScript在设计时,有两种比较运算符:
第一种是==
比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是===
比较,它不会自动转换数据类型,如果数据类型不一致,返回false
,如果一致,再比较。
由于JavaScript这个设计缺陷,不要使用==
比较,始终坚持使用===
比较。
另一个例外是NaN
这个特殊的Number与所有其他值都不相等,包括它自己:
- NaN === NaN; // false
唯一能判断NaN
的方法是通过isNaN()
函数:
- isNaN(NaN); // true
最后要注意浮点数的相等比较:
- 1 / 3 === (1 - 2 / 3); // false
这不是JavaScript的设计缺陷。浮点数在运算过程中会产生误差,因为计算机无法精确表示无限循环小数。要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:
- 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
表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用null
。undefined
仅仅在判断函数参数是否传递的情况下有用。
另一种创建数组的方法是通过Array()
函数实现:
- new Array(1, 2, 3); // 创建了数组[1, 2, 3]
对象
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
strict模式
JavaScript在设计之初,为了方便初学者学习,并不强制要求用var
申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var
申明就被使用,那么该变量就自动被申明为全局变量:
不用var
申明的变量会被视为全局变量,为了避免这一缺陷,所有的JavaScript代码都应该使用strict模式。我们在后面编写的JavaScript代码将全部采用strict模式。
数组
JavaScript的Array
可以包含任意数据类型,并通过索引来访问每个元素。
请注意,直接给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
大小的变化:
- var arr = [1, 2, 3];
- arr[5] = 'x';
- arr; // arr变为[1, 2, 3, undefined, undefined, 'x']
对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
JavaScript的对象用于描述现实世界中的某个对象。例如,为了描述“小明”这个淘气的小朋友,我们可以用若干键值对来描述他:
- var xiaoming = {
- name: '小明',
- birth: 1990,
- school: 'No.1 Middle School',
- height: 1.70,
- weight: 65,
- score: null
- };
最后一个键值对不需要在末尾加,
,如果加了,有的浏览器(如低版本的IE)将报错。
访问属性是通过.
操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''
括起来:
- var xiaohong = {
- name: '小红',
- 'middle-school': 'No.1 Middle School'
- };
xiaohong
的属性名middle-school
不是一个有效的变量,就需要用''
括起来。访问这个属性也无法使用.
操作符,必须用['xxx']
来访问:
如果访问一个不存在的属性会返回什么呢?JavaScript规定,访问不存在的属性不报错,而是返回undefined
:
如果我们要检测 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把null
、undefined
、0
、NaN
和空字符串''
视为false
,其他值一概视为true
,因此上述代码条件判断的结果是true
。
循环
- var x = 0;
- var i;
- for (i=1; i<=10000; i++) {
- x = x + i;
- }
- x; // 50005000
让我们来分析一下for
循环的控制条件:
- i=1 这是初始条件,将变量i置为1;
- i<=10000 这是判断条件,满足时就继续循环,不满足就退出循环;
- i++ 这是每次循环后的递增条件,由于每次循环后变量i都会加1,因此它终将在若干次循环后不满足判断条件
i<=10000
而退出循环。
for
循环最常用的地方是利用索引来遍历数组:
- var arr = ['Apple', 'Google', 'Microsoft'];
- var i, x;
- for (i=0; i<arr.length; i++) {
- x = arr[i];
- console.log(x);
- }
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', '2'
- console.log(a[i]); // 'A', 'B', 'C'
请注意,for ... in
对Array
的循环得到的是String
而不是Number
。
while
for
循环在已知循环的初始和结束条件时非常有用。而上述忽略了条件的for
循环容易让人看不清循环的逻辑,此时用while
循环更佳。
while
循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:
do ... while
最后一种循环是 do { ... } while()
循环,它和while
循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件:
- var n = 0;
- do {
- n = n + 1;
- } while (n < 100);
- n; // 100
用 do { ... } while()
循环要小心,循环体会至少执行1次,而for
和while
循环则可能一次都不执行。
Map和Set
Map
是一组键值对的结构,具有极快的查找速度。
举个例子,假设要根据同学的名字查找对应的成绩,如果用Array
实现,需要两个Array
:
- var names = ['Michael', 'Bob', 'Tracy'];
- var scores = [95, 75, 85];
给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。
如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个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'); // 88
Set
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"}
通过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) { // 遍历Array
- console.log(x);
- }
- for (var x of s) { // 遍历Set
- console.log(x);
- }
- for (var x of m) { // 遍历Map
- console.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'
注意,forEach()
方法是ES5.1标准引入的,
你需要测试浏览器是否支持。
Set
与Array
类似,但Set
没有索引,因此回调函数的前两个参数都是元素本身:
- var s = new Set(['A', 'B', 'C']);
- s.forEach(function (element, sameElement, set) {
- console.log(element);
- });
注意,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);
- });
1.Javascript 快速入门(主要)的更多相关文章
- JavaScript快速入门(四)——JavaScript函数
函数声明 之前说的三种函数声明中(参见JavaScript快速入门(二)——JavaScript变量),使用Function构造函数的声明方法比较少见,我们暂时不提.function func() { ...
- Web开发初探之JavaScript 快速入门
本文改编和学习自 A JavaScript Primer For Meteor 和 MDN Web教程 前文 Web开发初探 概述 本文以介绍 JavaScript 为主,初学者掌握本文的内容后,将能 ...
- javascript快速入门
这个在w3school在线文档讲解的很详细,还能在线练习. 所以我只写一些入门的东西和最常用的总结以及注意事项: JavaScript 是脚本语言 一般被人们称为JS,Jquery就是对js语言的封装 ...
- Javascript快速入门(上篇)
Javascript的熟练之路,小弟来了. JavaScript简介:JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript ...
- Javascript快速入门(下篇)
Javascript, cheer up. Ajax:其通过在Web页面与服务器之间建立一个额外的处理层,这个处理层就被称为Ajax引擎,它解释来自用户的请求,在后台以异步的方式处理服务器通信,其结构 ...
- javascript快速入门21--DOM总结
跨浏览器开发 市场上的浏览器种类多的不计其数,它们的解释引擎各不相同,期待所有浏览器都一致的支持JavaScript,CSS,DOM,那要等到不知什么时候,然而开发者不能干等着那天.历史上已经有不少方 ...
- javascript快速入门10--运算符,语句
一元运算符 一元运算符只有一个参数,即要操作的对象或值.它们是 ECMAScript 中最简单的运算符. delete 运算符删除对以前定义的对象属性或方法的引用.例如: var obj = new ...
- javascript快速入门8--值,类型与类型转换
原始值和引用值 在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值. 原始值(primitive value)是存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量 ...
- javascript快速入门2--变量,小学生数学与简单的交互
变量 对于变量的理解:变量是数据的代号.如同人的名字一样. var num;//在JavaScript中使用关键字var声明一个变量 在JavaScript中,使用上面的语法,就可以声明一个变量,以便 ...
- JavaScript 快速入门回顾
数据类型Number JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型: 123; // 整数123 0.456; // 浮点数0.456 1.2345e ...
随机推荐
- Mysql8.0在windows系统安装一直卡在Starting the server的解决方案
报错:Beginning configuration step: Starting Server Attempting to start service MySQL80 一直卡在这里,手动启动服务也起 ...
- 在uGUI正交相机中实现旋转透视效果
正常uGUI使用正交相机的话,旋转是没有透视效果的,但如果能实现较简单的透视, 对一些效果表现来说还是不错的:见下图(左为透视效果): 正常思路感觉各种麻烦. 因为uGUI使用unity的x和y方向表 ...
- USRP B210 软件定义的无线网络(SDR)支撑设备
目录 文章目录 目录 蜂窝网络 蜂窝网络的组成 USRP B210 USRP B210 的功能清单与相关参数 USRP B210 的系统结构与运行原理 相关知识储备 SDR RFIC RF 发展历程 ...
- 微信小程序订阅消息开发指南(java)
微信小程序订阅消息开发指南(java) 第一步 准备阶段 1.你得有一个小程序,并且认证了,个人的也行 2.开通订阅消息 小程序后台->功能->订阅消息 3.公共模板库选择一个模板 选择的 ...
- Chart.js (v2.9.4)概要介绍
chart.js是一个非常优秀的开源图表插件,扩展非常灵活,同时也提供了大量的钩子函数,给与用户添加自定义插件,实现个性化的需求. 具体的优势特点,这里不详述,网上大把资料,现开始正式深入了解这个插件 ...
- AIRIOT智慧变电站管理解决方案
随着社会电气化进程的加速,电力需求与日俱增,变电站作为电网的关键节点,其稳定性和智能化管理水平直接关系到整个电力系统的高效运作.传统变电站管理平台难以适应现代电力系统复杂管理需求,存在如下痛点: 数据 ...
- Android 13 - Media框架(4)- MediaPlayerService
关注公众号免费阅读全文,进入音视频开发技术分享群! MediaPlayerService是android的多媒体框架的核心服务之一,该服务存储有android平台所支援的编解码器信息,管理所有通过Me ...
- ReplayKit2 有线投屏项目总结
一.实现目标 iOS11.0以上设备通过USB线连接电脑,在电脑端实时看到手机屏幕内容 画质达到超清720级别,码率可达到1Mbps以上 二.实现技术方案设计 1.手机端采用ReplayKit2框架, ...
- 『手撕Vue-CLI』下载指定模板
开篇 经上篇文章的介绍,实现了获取下载目录地址,接下来实现下载指定模板的功能. 背景 通过很多章节过后,已经可以拿到模板名称,模板版本号,下载目录地址,这些信息都是为了下载指定模板做准备的. 实现 如 ...
- 「AntV」X6 自定义vue节点(vue3)
官方文档 本篇文档只讲解vue3中如何使用,vue2的可以参考下官方文档 安装插件 @antv/x6-vue-shape 添加vue组件 既然使用vue节点,那么我们就需要准备一个vue的组件,这个组 ...