ECMA 基础(一)

European Computer Manufactures Association

ECMAScriptJavaScript所基于的脚本语言。Ecma国际组织 负责将 ECMAScript标准化。

欧洲计算机制造联合会,位于日内瓦,致力于评估,开发,认可电信,制定了计算机标准List 清,ECMA-262 脚本语言的规范 ECMAScript里的ES5ES6标准

ECMAScript 历史:

  • 1997 年 1.0
  • 1998 年 2.0
  • 1999 年 3.0 通行标准
  • 2007 年 4.0 草案(mozilla支持, google, firefox, microsoft不支持)
  • 2008 年 4.0 中止,把容易改善的部分归纳到 3.1,激进部分(Harmony),更名为 ECMAScript5
  • 2009 年 5.0 正式发布,Harmony分成两部分,不怎么激进部分(JS.Next),比较激进部分(JS.Next.Next)
  • 2011 年,5.1 发布,成为 ISO国际标准
  • 2013 年,ES6不再增添内部,直接用 JS.Next,ES7 用 JS.Next.NextES6草案发布
  • 2015 年,ES6正式发布又名为 ECMAScript2015

内核

浏览器 内核
IE trident
chrome webkit blink
safari webkit
firefox gecko
opera presto

浏览器历史

  • 1990 年,蒂姆 伯纳斯 李 超文本分享资讯的人,world wide web 移植到 C libwww/nexus,允许别人浏览他人编写的网站
  • 1993 年,美国伊利诺大学 NCSA组织(马克 安德森),开发了 MOSIAC浏览器,可以显示图片,图形化浏览器
  • 1994 年,马克 安德森 和 吉姆 克拉克(硅图 SGI) 成立 MOSIAC communication corporation(因为商标纠纷而倒闭)插曲,MOSIAC属于伊利诺大学并将商标转让给 spy glass 公司(做数据的),在没办法的情况下改名为Netscape communication corporation 网景公司,并开发了netscape navigator 浏览器(流行了 10 年)
  • 1996 年,微软收购了 spy glass,开发了Internet Exploror 1.0,IE3 开发了 Jscript(实现网页动态交互)
  • 1996 年,网景公司 Brendan eichnetscape navigator 开发出了 livescript(JavaScript前身)
  • 1996 年,Java有一定的知名度了,网景 livescript不温不火,和 SUN公司商量合作推广和宣传产品,livescript发展更名为 JavaScript
  • 2001 年,IE6 XP 诞生,带来 JavaScript的生命-JS 引擎
  • 2003 年,Mozilla公司(早期互联网电子开发) firefox也是根据 netscape navigator 改版的
  • 2008 年,谷歌基于 webkit blink 内核加上 gears(离线上网功能) ,开发出 chrome浏览器(V8 引擎-JS引擎),直接翻译机器码,且独立于浏览器运行,并提出渐进式 APP(Progressive Web APP)
  • 2009 年,甲骨文 Oracle收购了 SUN公司,JavaScript的所有权给了甲骨文

编程语言

是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令,一种能够让程序员准确地定义计算机所需要使用数据的计算机语言,并精确地定义在不同情况下所应当采取的行动。

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。

编译与解释语言的区别:

一个是编译,一个是解释。两种方式只是翻译的时间不同。编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高,但也不能一概而论,部分解释型语言的解释器通过在运行时动态优化代码,甚至能够使解释型语言的性能超过编译型语言。
解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。解释是一句一句的翻译。

解释型语言的好处就是不需要根据不同的系统平台进行移植

脚本语言(前后端都有):

  • JavaScript客户端脚本
  • PHP服务器脚本

脚本语言 -> 脚本引擎 -> 解释器

JavaScript编程语言 4 要素:

  • 变量
  • 数据结构
  • 函数
  • 运算能力

JavaScript 概念

JavaScript分为:

  • 文档对象模型 (DOM) - document object model(W3C规范)
  • 浏览器对象模型(BOM) - browser object model(没有规范)
  • ESMAScript

关于 ESMAScript:

语法,变量,关键字,保留字,值,原始类型,引用类型运算,对象,继承,函数

线程

  • 单线程
  • 多线程

JavaScript引擎为单线程 -> 模拟多线程

单线程的机制是轮转时间片,短时间内轮流执行多个任务的片段

  1. 任务 1,任务 2
  2. 切分任务 1,任务 2
  3. 随机排列这些任务片段,组成队列
  4. 按照这个队列顺序将任务片段送进 JS进程
  5. JS线程执行一个又一个的任务片段

引用

  • 外部文件
  • 内部脚本代码块
  1. //外部文件
  2. <script type="text/javascript" src="js/index.js"></script>
  1. //内部文件
  2. <script type="text/javascript">
  3. document.write('I am a inner JS');
  4. </script>

变量

变量是一个容器用于存储数据后续使用

声明变量 var

  • 声明变量
  • 变量赋值
  1. var a; //声明变量a
  2. a = 3; //变量赋值
  3. var a = 3; //变量声明并赋值
  1. //单一声明
  2. var x = 1,
  3. y = 2;

企业开发命名规范:

  • 不能以数字开头
  • 能字母 _, $开头
  • 字母_,$数字
  • 不能关键字
  • 不能保留字
  • 语义化
  • 结构化(js_header js-header)
  • 小驼峰
  • 英语写法
  • 避免拼音

优先级:

运算 > 赋值

  1. var x = 3,
  2. y = 4;
  3. var z = x + y;
  4. console.log(z);
  5. //print
  6. 7

JS 值

JavaScript语言是动态语言也是脚本语言也是解释型语言也是弱类型语言(根据值的类型成为被赋值的变量)

Java语言是静态语言也是编译型语言也是强类型语言

原始值

基本数据类型有NumberStringBooleanundefinednull

Number

  1. var a = 1;
  2. var a = 3.14;

String

  1. var str = 'i love programing';

Boolean

布尔值(布尔发明),计算机里,非真即假,非假即真。

  • true
  • false
  1. var a = true;
  2. console.log(a);
  3. //true

undefined

  1. 系统会给一个未赋值的变量自动赋值为undefined,类型也是undefined
  2. 函数没有传入实参时,参数为undefined
  3. 函数没有返回值时,默认返回undefined
  1. var a = undefined;
  2. console.log(a);
  3. //undefined
  1. var a;
  2. console.log(a);
  3. //undefined
  • undefined既是一个原始数据类型,也是一个原始值数据
  • undefined是全局对象上的一个属性window.undefined
  • undefined不可写writable: false
  • undefined不可配置configurable: false
  • undefined不可枚举enumerable: false
  • undefined不可重新定义defineProperty
  • 全局下,undefined无法作为一个变量使用
  • 局部作用域下,undefined可以作为一个变量使用,说明undefined不是 JS 的保留字和关键字

void(0) === undefined

null

空值,它的作用在于

  • 初始化组件
  • 销毁函数

引用值

引用值有objectarrayfunctiondateRegExp

堆栈

  • 栈内存 Stack
  • 堆内存 Heap

如何存储原始值?

ECMA(一)基础语法 - 图1

栈内存先进后出

  1. var a = 3;
  2. var b = a;
  3. a = 1;
  4. console.log(b); //3

存储步骤:

  1. 往内存空间最里面声明变量 a 并在空间里存入值 3(var a = 3)
  2. 往内存空间最里面的上一位声明变量 b 并在空间里存入值 3(var b = a)
  3. 往内存空间最里面的上上一位开辟空间里存入值 1(a = 1)

说明原始值数据是永久保存且不可改变的,例如手机相机电脑内存删除内容其实数据仍保留

如何存储引用值?

值,指针存储在栈 Stack内存 指向 堆内存 Heap地址

ECMA(一)基础语法 - 图2

  1. var arr1 = [1, 2, 3, 4];
  2. var arr2 = arr1;
  3. console.log(arr1 + '' + arr2);
  4. //1, 2, 3, 4 | 1, 2, 3, 4

指向相同地址的情况:

  1. var arr1 = [1, 2, 3, 4];
  2. var arr2 = arr1;
  3. arr1.push(5);
  4. console.log(arr1); //1, 2, 3, 4, 5
  5. console.log(arr2); //1, 2, 3, 4, 5

指向不同地址的情况:

  1. var arr1 = [1, 2, 3, 4];
  2. var arr2 = arr1;
  3. arr1 = [1, 2];
  4. console.log(arr1); //1, 2
  5. console.log(arr2); //1, 2, 3, 4, 5

规范

  • 结束语句写分号
  • forifswitchfunction语句可以不加分号
  • 单一声明模式可以不加分号var a = 1, b = 2;
  • 符号两边加空格+=

错误

  • 语法问题:如有错误,代码一句都不执行Uncaught SyntaxError
  • 通用问题:中断执行

    • 引用错误 Uncaught ReferenceError
    • 类型错误 Uncaught TypeError

多个代码块之间的错误不影响下面代码块的执行

  1. <script type="text/javascript">
  2. console.log(1)
  3. </script>
  4. <script type="text/javascript">
  5. console.log(1);
  6. </script>

运算符

+-*/%()

加号运算符

  1. var a = 1,
  2. b = 2,
  3. c;
  4. c = a + b;
  5. console.log(c); //3
  1. var a = 1,
  2. b = 2,
  3. d = 3,
  4. c;
  5. c = a + b * d;
  6. console.log(c); //7

优先级:括号运算 > 普通运算 > 赋值

  1. var a = 1,
  2. b = 2,
  3. d = 3,
  4. var c = (a + b) * d;
  5. console.log(c); //9
  6. //计算机步骤:
  7. //1.声明变量
  8. //2.变量a的值和变量b的值相加,与变量d的值相乘得到结果
  9. //3.将该结果赋值给变量c

字符串拼接,任何数据类型的值 + 字符串 = 字符串

  1. var a = 1,
  2. b = 2,
  3. c;
  4. c = 1 + 'str'; //console.log(c); 1str
  5. c = 'str' + 'str'; //console.log(c); strstr
  6. c = 'str' + undefined; //console.log(c); strundefined
  7. c = 'str' + null; //console.log(c); strnull
  8. c = 'str' + true; //console.log(c); strtrue
  9. c = 'str' + NaN; //console.log(c); strNaN
  10. c = 'str' + 1 + 1; //console.log(c); str11
  11. c = 'str' + (1 + 1); //console.log(c); str2
  12. c = 1 + 1 + 'str' + (1 + 1); //console.log(c); 2str2

减号运算符

减号 加 字符串会先转为数字

  1. var num = '123';
  2. console.log(typeof(- num) + ':' + - num); //number : -123
  1. var num = 'abc';
  2. console.log(typeof(- num) + ':' + - num); //number : NaN

除号运算符

  1. //除法
  2. var a = 10,
  3. b = 2,
  4. c;
  5. c = a / b; console.log(c); //5
  6. c = 0 / 0; console.log(c); //NaN -> Not a Number 数字类型
  7. console.log(1 / 0); //Infinity 正无穷 数字类型
  8. console.log(-1 / 0); //-Infinity 负无穷 数字类型

余号运算符

  1. console.log(5 % 2); //1 5-(2*2)=1
  2. console.log(5 % 3); //2 5-(1*3)=2
  3. console.log(4 % 6); //4 前面比后面小,取前面

交换值的问题:

方法一

  1. var a = 1,
  2. b = 2;
  3. //a b的值交换
  4. var c = a, //c = 1
  5. a = b, //a = 2
  6. b = c; //b = 1
  7. console.log(a, b); //2 1

方法二

  1. var a = 1,
  2. b = 2;
  3. //a b的值交换
  4. a = a + b; //a = 3
  5. b = a - b; //b = 3 - 2 = 1
  6. a = a - b; //a = 3 - 1 = 2
  7. console.log(a, b); //2 1

++&--

  1. //var a = 1; a = a + 1; => a++
  2. var a = 1;
  3. console.log(a++); //1 先打印后运算
  4. console.log(a); //2
  5. console.log(++a); //2 先运算赋值再打印
  6. console.log(a = a + 1); //2
  1. var a = 5;
  2. console.log(a--); //5 先打印后运算
  3. console.log(a); //4
  4. console.log(--a); //4 先运算赋值再打印
  1. var a = 5,
  2. b;
  3. b = a++ + 1;
  4. console.log(b, a); //6 6
  1. var a = 5,
  2. b;
  3. b = ++a + 1;
  4. console.log(b, a); //7 6
  1. var a = 5,
  2. b;
  3. b = a-- + --a; //5 + 3
  4. console.log(b, a); //8 3
  1. var a = 5,
  2. b;
  3. b = --a + --a; //4 + 3
  4. console.log(b, a); //7 3
  1. var a = 5,
  2. b;
  3. b = --a + a++; //4 + 4
  4. console.log(b, a); //8 5

比较运算符

  • >大于
  • <小于
  • >=大于等于
  • <=小于等于
  • ==相等
  • ===全等
  • !=不相等
  • !==不全等

number比较 number

  1. var bool = 1 > 2;
  2. console.log(bool); //false
  1. var bool = 1 < 2;
  2. console.log(bool); //true

number比较 stringstring先转化成 number再进行比较

  1. var bool = 1 > '2';
  2. console.log(bool); //false
  1. var bool = 1 < '2';
  2. console.log(bool); //true

string比较 string,寻找对应 ASCII码的十进制数字对比,多个字符的,从左到右依次对比,直到比较出 ASCII码的大小为止

  1. var bool = 'a' > 'b';
  2. //a -> 97(ASCII码对应的十进制数字)
  3. //b -> 98(ASCII码对应的十进制数字)
  4. console.log(bool); //false
  1. var bool = 'a' < 'b';
  2. console.log(bool); //true

为什么 4.5 > 11? 因为 ASCII码对应 ASCII码的十进制数字

  1. var bool = '4.5' > '11';
  2. //先比较前面的4 和 1 然后再逐个往后对比
  3. //显然4(52) > 1(49),对比结束
  4. //4 -> 52(ASCII码对应的十进制数字)
  5. //1 -> 49(ASCII码对应的十进制数字)
  6. console.log(bool); //true
  1. var bool = '4.5' < '11';
  2. console.log(bool); //false
  1. var bool = '1.5' > '11';
  2. //先比较前面的1 和 1 然后再逐个往后对比
  3. //首先1(52) = 1(52)
  4. //然后.(46) < 1(52)
  5. console.log(bool); //false

==,相等是不看数据类型的,全等需要看数据类型是否相等的

  1. var bool = 1 == 1;
  2. console.log(bool); //true
  1. var bool = 1 == '1';
  2. console.log(bool); //true
  1. var bool = 1 === '1';
  2. console.log(bool); //false

!=,

  1. var bool = 1 != 1;
  2. console.log(bool); //false
  1. var bool = 1 != 2;
  2. console.log(bool); //true
  1. var bool = 1 != '1';
  2. console.log(bool); //true

NaN与包括自己在内任何东西都不相等

  1. var bool = NaN == NaN;
  2. console.log(bool); //false

if语句

判断分支之if语句

  1. if(条件){
  2. 语句;
  3. }
  • 在条件中&&就是并且,&&两边都必须满足条件即可
  • ||就是或者,||两边有一边满足条件即可

查询成绩等级:

  1. var score = 63;
  2. if (score >= 90) {
  3. console.log('您的成绩等级为A');
  4. }
  5. if (score >= 80 && score < 90) {
  6. console.log('您的成绩等级为B');
  7. }
  8. if (score >= 70 && score < 80) {
  9. console.log('您的成绩等级为C');
  10. }
  11. if (score >= 60 && score < 70) {
  12. console.log('您的成绩等级为D');
  13. }
  14. if (score < 60) {
  15. console.log('您的成绩等级为不合格');
  16. }

以上的if语句不管是否匹配成功条件都要继续往下匹配,造成性能影响,可以改为以下写法

  1. var score = 63;
  2. if (score >= 90 && score <= 100) {
  3. console.log('您的成绩等级为A');
  4. } else if (score >= 80 && score < 90) {
  5. console.log('您的成绩等级为B');
  6. } else if (score >= 70 && score < 80) {
  7. console.log('您的成绩等级为C');
  8. } else if (score >= 60 && score < 70) {
  9. console.log('您的成绩等级为D');
  10. } else if (score < 60 && score >= 0) {
  11. console.log('您的成绩等级为不合格');
  12. } else {
  13. console.log('您的成绩出现异常');
  14. }

switch语句

判断分支之switch语句

  1. switch(变量){
  2. case 值:
  3. 语句;
  4. default:
  5. 语句;
  6. }

注: case相当于 当值为 ,default相当于else

  1. var city = window.prompt('请输入您所在的地区');
  2. switch (city) {
  3. case '北京':
  4. console.log('15k');
  5. case '上海':
  6. console.log('13k');
  7. case '深圳':
  8. console.log('12k');
  9. case '广州':
  10. console.log('11k');
  11. default:
  12. console.log('9k');
  13. }
  14. //输入北京 print
  15. 15k
  16. 13k
  17. 12k
  18. 11k
  19. 9k

如果缺少break断开,代码会执行往下执行,所以加上break匹配到条件就不会往下执行

  1. var city = window.prompt('请输入您所在的地区');
  2. switch (city) {
  3. case '北京':
  4. console.log('15k');
  5. break;
  6. case '上海':
  7. console.log('13k');
  8. break;
  9. case '深圳':
  10. console.log('12k');
  11. break;
  12. case '广州':
  13. console.log('11k');
  14. break;
  15. default:
  16. console.log('9k');
  17. }
  18. //输入北京 print
  19. 15k

关于适用性:

  • 有值范围的或者条件是多个的用if语句恰当
  • 定值或者多个以上的用switch语句比较好

三目运算符

三元运算符

  1. var a = 5;
  2. if (a > 0) {
  3. console.log('大于0');
  4. } else {
  5. console.log('小于0');
  6. }
  7. a > 0 ? console.log('大于0')
  8. : console.log('小于0');

简写

  1. a > 0 ? str = '大于0' : str = '小于0';
  1. var str = a > 0 ? '大于0' : '小于0';

嵌套写法

  1. var a = 5,
  2. str = '';
  3. if (a > 0) {
  4. if (a > 3) {
  5. str = '大于3';
  6. } else {
  7. str = '小于等于3';
  8. }
  9. } else {
  10. str = '小于0'
  11. }
  12. str = a > 0 ? (a > 3 ? '大于3' : '小于等于3') : '小于0'
  13. console.log(str);

逻辑运算

假包括:undefinednullNaN空字符串0false

除以上假的都为真

&&

核心:

遇到真就往后走

  1. var a = 1 && 2;
  2. console.log(a); //2

遇到假或走到最后就返回当前的值

  1. var a = 1 && 2 && undefined && 10;
  2. console.log(a); //undefined

总结:

&&前面和后面都满足条件才能使if语句(为真)继续进入往下执行

  1. //1 && 1 返回1 真
  2. //0 && 1 返回0 假
  3. //1 && 0 返回0 假
  4. //0 && 0 返回0 假
  5. //if(... && ...){}

||

核心:

遇到假就往后走

  1. var b = 1 || 2;
  2. console.log(b); //1

遇到真或者走到最后就返回当前的值

  1. var b = 0 || null || 1 || 0;
  2. console.log(b); //1

总结:

||前面或后面有一个能满足条件if语句(为真)条件就可继续进入往下执行

  1. //1 || 1 返回1 真
  2. //0 || 1 返回1 真
  3. //1 || 0 返回1 真
  4. //0 || 0 返回0 假
  5. if(... || ...){}

!

  1. var a = !1;
  2. console.log(a); //false
  3. var a = !!1;
  4. console.log(a); //true

注释

  • 行注释
  • 块注释

正确写法:

  1. /**
  2. * 123
  3. * 345
  4. */

错误写法:

  1. /*
  2. 123
  3. 345
  4. */

循环语句

多次执行相同代码

if & while语句

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

步骤

  1. 1.声明变量 i = 0;
  2. 2.if(i < 3){
  3. console.log(i); //0
  4. }
  5. 3.i++;
  6. 4.if(i < 3){
  7. console.log(i); //1
  8. }
  9. 5.i++;
  10. ...
  11. 6.if(i < 3){ 不满足条件 停止循环
  12. console.log(i); //1
  13. }

换种写法:

  1. var i = 0;
  2. for(; i < 3;){
  3. console.log(i);
  4. i++;
  5. }

写法类似于while循环:

  1. var i = 0;
  2. while(i < 3){
  3. console.log(i);
  4. i++;
  5. }

说明for循环可以转换为while循环

死循环:

  1. var i = 0;
  2. //1 条件永远满足会一直执行
  3. while(1){
  4. console.log(i);
  5. i++;
  6. }

没有条件的情况也是死循环:

  1. var i = 1;
  2. for(; i;){
  3. console.log(1);
  4. i++;
  5. }

跳出死循环并打印 1-10

  1. var i = 1;
  2. for (; i;) {
  3. console.log(i);
  4. i++;
  5. if (i == 11) {
  6. i = 0; //or break
  7. }
  8. }

从 0 开始做加法,加到什么时候总和是小于 100 的

  1. var sum = 0;
  2. for (var i = 0; i < 100; i++) {
  3. sum += i;
  4. if (sum > 100) {
  5. break;
  6. }
  7. console.log(i, sum);
  8. }

100 以内的数 跳过可以被 7 整除 或个位数是 7 的数

  1. for (var i = 0; i <= 100; i++) {
  2. if (i % 7 == 0 || i % 10 == 7) {
  3. } else {
  4. console.log(i);
  5. }
  6. }

continue可以直接跳过循环打印结果

  1. for (var i = 0; i <= 100; i++) {
  2. if (i % 7 == 0 || i % 10 == 7) {
  3. continue;
  4. }
  5. console.log(i);
  6. }

打印 0-9

  1. for (var i = 0; i < 10; i++) {
  2. console.log(i);
  3. }

打印 1-10

  1. for (var i = 1; i <= 10; i++) {
  2. console.log(i);
  3. }

打印 0-9 的和

  1. var sum = 0;
  2. for (var i = 0; i < 10; i++) {
  3. sum += i;
  4. }
  5. console.log(sum); //45

可以被 4,5,6 整除的数

  1. for (var i = 0; i <= 100; i++) {
  2. if (i % 4 == 0 || i % 5 == 0 || i % 6 == 0) {
  3. console.log(i);
  4. }
  5. }

面试题:打印 0-100 的数,且又条件如下:

  • ()只能有一句,不能写比较
  • {}不能出现i++i--
  1. var i = 101;
  2. //i-- 如果到0就会自动结束循环
  3. //只能写分号中间,条件判断语句 0的时候就为false
  4. for (; i--;) {
  5. console.log(i);
  6. }

do while语句

特点:无论条件是否成立都要先执行

  1. var i = 0;
  2. while (i < 10) {
  3. console.log(i);
  4. i++;
  5. }
  1. var i = 0;
  2. do {
  3. console.log('我要开始循环了', i);
  4. i++;
  5. } while (i < 10);

10 的 n 次方

  1. //10 100 1000 10000 100000
  2. var n = 5;
  3. var num = 1;
  4. for (var i = 0; i < n; i++) {
  5. num *= 10; //num = num * 10
  6. }
  7. console.log(num); //100000

n 的阶乘

  1. var n = 5;
  2. var num = 1;
  3. for (var i = 1; i <= 5; i++) {
  4. num *= i; //num = num * i
  5. }
  6. console.log(num); //120

运算题:

求数字 789 反转后的数字 987

知识拓展:

被除数:789 除数:10 商数:78 余数:9

  • 公式 1:除数 * 商数 + 余数 = 被除数
  • 公式 2(被除数%除数 ):

    • 商数 = 被除数 / 除数 (取整数)
    • 余数 = 被除数 / 除数 (取小数 * 除数)
  1. var num = 789;
  2. var a = num % 10; //789 % 10 = 9
  3. var b = (num - a) % 100 / 10; //(789 - 9) % 100 = 80
  4. var c = (num - a - b * 10) / 100; //(789 - 9 - 80) % 100 = 7
  5. console.log(a); //9
  6. console.log(b); //8
  7. console.log(c); //7
  8. console.log('' + a + b + c); //987

打印三个数中的最大的数

  1. var a = 1,
  2. b = 2,
  3. c = 3;
  4. if (a > b) {
  5. if (a > c) {
  6. console.log(a);
  7. } else {
  8. console.log(c);
  9. }
  10. } else {
  11. if (b > c) {
  12. console.log(b);
  13. } else {
  14. console.log(c);
  15. }
  16. }
  17. //3

打印 100 以内的质数

质数:除了 1 和此整数自身外,没法被其他自然数整除的数。

100 以内的素数素数的规律如下:

  1. 个位是偶数的只有 2;
  2. 个位是 5 的只有 5;
  3. 个位是 1 的有 11、31、41、61、71,共 5 个;
  4. 个位是 3 的有 3、13、23、43、53、73、83,共 7 个;
  5. 个位是 7 的有 7、17、37、47、67、97,共 6 个;
  6. 个位是 9 的有 19、29、59、79、89,共 5 个。

注:个位十位数字相同的除了 11 外,其它都不是素数。

100 以内的素数共 25 个,如下:  2,3,5,7,11,13,17,19,23,29,31,37,41,43,

47,53,59,61,67,71,73,79,83,89,97

  1. //仅仅能被1 和自己整除的数
  2. var c = 0;
  3. //i 必须以2开始因为质数第一位是2
  4. //i < 100 100以内不包括100
  5. for (var i = 2; i < 100; i++) {
  6. //j 必须以1开始因为i % j 的时候i必须大于j
  7. for (var j = 1; j <= i; j++) {
  8. //第1轮 2 % 1 == 0
  9. //第2轮 2 % 2 == 0
  10. //第3轮 2 % 3 == 2 跳出
  11. //第4轮 3 % 1 == 0
  12. //第5轮 3 % 2 == 1
  13. //第6轮 3 % 3 == 0
  14. //第7轮 3 % 4 == 3 跳出
  15. //第8轮 4 % 1 == 0
  16. //第9轮 4 % 2 == 0
  17. //第10轮 4 % 3 == 1
  18. //第11轮 4 % 4 == 0
  19. //第12轮 4 % 5 == 0
  20. //第13轮 5 % 1 == 0
  21. //第14轮 5 % 2 == 1
  22. //第14轮 5 % 3 == 2
  23. //第15轮 5 % 4 == 1
  24. //第16轮 5 % 5 == 0
  25. //第17轮 5 % 6 == 5 跳出
  26. //...
  27. if (i % j == 0) {
  28. c++;
  29. //第1轮 c = 0
  30. //第2轮 c = 1
  31. //第3轮 c = 2
  32. //第4轮 c = 0
  33. //第5轮 c = 1
  34. //第6轮 c = 1
  35. //第7轮 c = 2
  36. //第8轮 c = 0
  37. //第9轮 c = 1
  38. //第10轮 c = 2
  39. //第11轮 c = 2
  40. //第12轮 c = 3
  41. //第13轮 c = 0
  42. //第13轮 c = 1
  43. //第13轮 c = 1
  44. //第14轮 c = 1
  45. //第15轮 c = 1
  46. //第16轮 c = 1
  47. //第17轮 c = 2
  48. //...
  49. }
  50. }
  51. console.log(i, j, c);
  52. if (c == 2) {
  53. console.log('质数为:' + i);
  54. //2 3 5
  55. }
  56. c = 0;
  57. }

显式类型转换

任何 typeoftypeof的结果都为 string

  1. console.log(typeof (a)); //'undefined'
  2. console.log(typeof (123)); //'number'
  3. console.log(typeof ('')); //string
  4. console.log(typeof (typeof (a))); //string
  5. console.log(typeof (typeof (123))); //string

JS 的typeof()可能返回的值有:object/boolean/number/string/undefined/function

  1. //JS的typeof可能返回的值有哪些?
  2. //object/boolean/number/string/undefined
  3. console.log(typeof ('abc')); //string
  4. console.log(typeof (1)); //number
  5. console.log(typeof (true)); //boolean
  6. console.log(typeof (undefined)); //undefined
  7. console.log(typeof (null)); //object
  8. console.log(typeof ({})); //object
  9. console.log(typeof ([])); //object
  10. console.log(typeof (function () {})); //function

显式类型转换

number()

  1. var a = '123';
  2. console.log(Number(a)); //123
  3. console.log(Number(a) + '-' + typeof (Number(a))); //123-number
  4. console.log(typeof (Number(a)) + '-' + Number(a)); //number-123

Number()字符串,undefined转化为NaN,对布尔值先转化为 0 或 1 再转化为数字,对null转为 0

  1. console.log(Number('true')); //NaN
  2. console.log(Number(true)); //1
  3. console.log(Number(false)); //0
  4. console.log(Number(null)); //0
  5. console.log(Number(undefined)); //NaN
  6. console.log(Number('3.14')); //3.14
  7. console.log(typeof (NaN)); //number
  8. console.log(typeof (1)); //number
  9. console.log(typeof (0)); //number
  10. console.log(typeof (0)); //number
  11. console.log(typeof (NaN)); //number
  12. console.log(typeof (3.14)); //number
  13. console.log(typeof (Number('true')) + '-' + Number('true')); //number-NaN
  14. console.log(typeof (Number(true)) + '-' + Number(true)); //number-1
  15. console.log(typeof (Number(false)) + '-' + Number(false)); //number-0
  16. console.log(typeof (Number(null)) + '-' + Number(null)); //number-0
  17. console.log(typeof (Number(undefined)) + '-' + Number(undefined)); //number-NaN
  18. console.log(typeof (Number('3.14')) + '-' + Number('3.14')); //number-3.14

parseInt()

parseInt()把一个数转化整形,对true,false,null,字符串undefined都转换为NaN

  1. var a = '3.14';
  2. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-3
  1. var a = '123';
  2. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-123
  3. var a = 'true';
  4. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN
  5. var a = true;
  6. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN 这里parseInt()不管布尔值是否先转换为1,而是直接整形为NaN
  7. var a = false;
  8. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN 这里parseInt()不管布尔值是否先转换为1,而是直接整形为NaN
  9. var a = NaN;
  10. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN
  11. var a = undefined;
  12. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN
  13. var a = null;
  14. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN
  15. var a = '123';
  16. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-123
  17. var a = '';
  18. console.log(typeof (parseInt(a)) + '-' + parseInt(a)); //number-NaN

parseInt()如果是字符串开头得到的是NaN,数字开头得到截取数字开头的数字

  1. var a = 'b';
  2. console.log(parseInt('abc123')); //NaN
  3. console.log(parseInt('123abc')); //123

关于十六进制:

0123456789abcdef

16 进制 -> 颜色值 16 值 HEX 颜色值 #fff or #f0f0f0

parseFloat()

  1. console.log(parseFloat('3.14')); //3.14

保留小数点后两位

  1. var num = parseFloat('3.1415926');
  2. console.log(num.toFixed(2)); //3.14(str) 四舍五入

string()

  1. console.log(String(123)); //'123'
  2. console.log(typeof (String(123))); //string
  3. console.log(typeof ('' + 123)); //string
  4. console.log(typeof (123 + '')); //string

toString()

  1. var str = '3.14';
  2. console.log(str.toString()); //3.14

undefinednull没有toString()方法

  1. var str = undefined;
  2. var str = null;
  3. console.log(str.toString()); //报错

toString(radix)可以填写进制参数,以十进制为基础转化为目标进制

  1. var str = '100';
  2. //以二进制为基础转化为十进制的数
  3. console.log(parseInt(str, 2)); //4
  4. //以十进制为基础转化为十六进制的数
  5. console.log(parseInt(str, 2).toString(16)); //4

Boolean()

  1. console.log(Boolean(1)); //true
  2. console.log(Boolean(null)); //false
  3. console.log(Boolean(false)); //false
  4. console.log(Boolean(undefined)); //false
  5. console.log(Boolean(NaN)); //false
  6. console.log(Boolean(0)); //false
  7. console.log(Boolean('')); //false

隐式类型转换

加减乘除余

加号会将字符串转为数字

  1. var a = '123'; //Number(a);
  2. a++;
  3. console.log(a); //124

字符串拼接会隐式将数字转变为字符串再拼接

  1. var a = 'a'+ 1; //String(1);
  2. console.log(a); //a1

乘除余减都会由 string 转 number 的过程

  1. var a = '3'* 2;
  2. console.log(a); //6

比较运算

遇到比较运算符先转换为 number

  1. var a = '1' > 2;
  2. console.log(a); //false
  3. var a = 1 > '2';
  4. console.log(a); //false

两个字符串相比较的时候会转化为 ASCII 码

  1. var a = 'a' > 'b';
  2. console.log(a); //false

相等==

  1. var a = 1 == '1';
  2. console.log(a); //true

不等!=

  1. var a = 1 != '2';
  2. console.log(a); //true

全等===不进行数据类型转换

  1. var a = 1 === '1';
  2. console.log(a); //false

NaN不等于任何东西,连自己都不等

  1. var a = NaN == NaN;
  2. console.log(a); //false
  3. var a = NaN === NaN;
  4. console.log(a); //false
  1. //2 > 1 => true = 1 > 3 => false
  2. var a = 2 > 1 > 3;
  3. console.log(a); //false
  1. //2 > 1 => true = 1 == 1 => true
  2. var a = 2 > 1 == 1;
  3. console.log(a); //true

undefined跟数字相比较都为 falsenull跟数字相比较都为 falseundefinednull是相等关系但不是全等关系

  1. var a = undefined > 0;
  2. console.log(a); //false
  3. var a = undefined < 0;
  4. console.log(a); //false
  5. var a = undefined == 0;
  6. console.log(a); //false
  7. var a = null > 0;
  8. console.log(a); //false
  9. var a = null < 0;
  10. console.log(a); //false
  11. var a = null == 0;
  12. console.log(a); //false
  13. var a = undefined == null;
  14. console.log(a); //true
  15. //undefined和null并不是一个数据类型
  16. var a = undefined === null;
  17. console.log(a); //false

isNaN()

可以判断是否为 非数字,都需要先进行Number()再判断

  1. console.log(isNaN(NaN)); //true
  2. console.log(isNaN(123)); //false
  3. //Number('123') => 123
  4. console.log(isNaN('123')); //false
  5. console.log(isNaN('a')); //true
  6. //null => 0 不是非数字
  7. console.log(isNaN(null)); //false
  8. //Number(undefined) => NaN
  9. console.log(isNaN(undefined)); //true

ASCII 码

UNICODE码涵盖 ASCII

注: 可以用charCodeAt()方法查询

  • 表 1 字符为一个字节对应 0-127
  • 表 2 字符为两个字节对应 128-255

语法

  1. //index 字符串中某个位置的数字,即字符在字符串中的下标。
  2. stringObject.charCodeAt(index);

严格模式

ES5开始有严格模式和非严格模式,IE9及以下不支持严格模式

'use strict'

  1. //自己函数或模块里面写
  2. function test() {
  3. //最上一行
  4. 'use strict';
  5. }

with改变作用域,在严格模式下不能用,性能低

  1. // 'use strict';
  2. var a = 1;
  3. var obj = {
  4. a: 2
  5. };
  6. //with(作用域名称){}
  7. //严格模式不能使用with表达式
  8. function test() {
  9. var a = 3;
  10. with(test) {
  11. console.log(a); //3
  12. }
  13. with(obj) {
  14. console.log(a); //2
  15. }
  16. with(window) {
  17. console.log(a); //1
  18. }
  19. }
  20. test();

caller, callee,这些属性都不通过

  1. 'use strict';
  2. //caller callee
  3. function test1() {
  4. console.log(arguments.callee);
  5. }
  6. test1(1, 2, 3);
  7. //Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode
  8. function test2() {
  9. test3();
  10. }
  11. function test3() {
  12. console.log(arguments.caller);
  13. }
  14. //Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode

严格模式下必须声明变量

  1. 'use strict';
  2. a = 1;
  3. //Uncaught ReferenceError: a is not defined

重复赋值报错

  1. 'use strict';
  2. var a = b = 1;
  3. //Uncaught ReferenceError: b is not defined

严格模式下函数内部this指向undefined,实例化后this指向对象本身

  1. 'use strict';
  2. //非严格模式指向window
  3. function test() {
  4. console.log(this);
  5. }
  6. test(); //undefined
  7. new test(); //test{}

call/apply

  1. // 'use strict';
  2. function test() {
  3. console.log(this);
  4. }
  5. //非严格模式call()
  6. test.call(1); //指向包装类Number()对象
  7. test.call({}); //指向test对象
  8. //严格模式call()
  9. test.call(1); //指向1
  10. test.call({}); //指向{}

函数参数不能重复

  1. 'use strict';
  2. function test(a, a) {
  3. console.log(a);
  4. }
  5. test(1, 2);
  6. //非严格模式
  7. //2
  8. //严格模式
  9. //Uncaught SyntaxError: Duplicate parameter name not allowed in this context

对象属性名不允许重复

  1. 'use strict';
  2. var obj = {
  3. a: 1,
  4. a: 2
  5. }
  6. console.log(obj.a);
  7. //非严格模式
  8. //2
  9. //严格模式
  10. //2 不报错

错误信息

  • SyntaxError 语法错误

    • 变量名不规范
    • 关键字赋值
    • 基本的语法错误
  • ReferenceError引用错误

    • 变量或者函数未被声明
    • 给无法被赋值的对象赋值
    • RangeError范围错误
    • TypeError类型错误
    • URIError URI错误
    • EvalError eval函数执行错误
  • 人为抛出的错误
  1. //变量名不规范
  2. var 1 = 1;
  3. //Uncaught SyntaxError: Unexpected number
  4. var 1ab = 1;
  5. function 1 test() {}
  6. //Uncaught SyntaxError: Invalid or unexpected token
  1. //关键字赋值
  2. new = 5;
  3. //Uncaught SyntaxError: Unexpected token '='
  4. function = 1;
  5. //Uncaught SyntaxError: Unexpected token '='
  1. //基本的语法错误
  2. var a = 5:
  3. //Uncaught SyntaxError: Unexpected token ':'
  1. //变量或者函数未被声明
  2. test();
  3. //Uncaught ReferenceError: test is not defined
  4. console.log(a);
  5. //Uncaught ReferenceError: a is not defined
  1. //给无法被赋值的对象赋值
  2. var a = 1 = 2;
  3. console.log(a) = 1;
  4. //Uncaught SyntaxError: Invalid left-hand side in assignment
  1. //RangeError范围错误
  2. //数组长度赋值为负数
  3. var arr = [1, 2, 3];
  4. arr.length = -1;
  5. console.log(arr);
  6. //Uncaught RangeError: Invalid array length
  7. //对象方法参数超出可行范围
  8. var num = new Number(66.66);
  9. console.log(num.toFixed(-1));
  10. //Uncaught RangeError: toFixed() digits argument must be between 0 and 100
  1. //TypeError 类型错误
  2. //调用不存在的方法
  3. 123();
  4. //Uncaught TypeError: 123 is not a function
  5. var obj = {};
  6. obj.say();
  7. //Uncaught TypeError: obj.say is not a function
  8. //实例化原始值
  9. var a = new 'string';
  10. var a = new 123;
  11. //Uncaught TypeError: "string" is not a constructor

关于 URL

  1. //URIError URI错误
  2. //URI: UNIFORM RESOURCE IDENTIFIER 统一资源标识符
  3. //URL: UNIFORM RESOURCE LOCATOR 统一资源定位符
  4. //URN: UNIFORM RESOURCE NAME 统一资源名称
  5. //URL和URN属于URI
  6. //URL: http://www.baidu.com/news#today 协议+域名+资源空间
  7. // ftp://www.baidu.com/ftp#developer
  8. //URN: www.baidu.com/ftp#developer 代表资源唯一的标识 -> ID
  9. // href="tel:13900000000"
  1. //URLError URI错误
  2. var myUrl = 'http://www.baidu.cin?name=哈哈哈';
  3. //把中文字转化为中文编码字符
  4. var newUrl = encodeURI(myUrl);
  5. console.log(newUrl);
  6. //http://www.baidu.cin?name=%E5%93%88%E5%93%88%E5%93%88
  7. //把中文编码字符转化为中文字
  8. var newNewUrl = decodeURI(newUrl);
  9. console.log(newNewUrl);
  10. //http://www.baidu.cin?name=哈哈哈
  11. var str = decodeURI('%fsdcf%');
  12. //Uncaught URIError: URI malformed
  1. //人为抛出的错误
  2. var error = new Error();
  3. var error2 = new SyntaxError();
  4. var error3 = new ReferenceError();
  5. var error4 = new TypeError();

异常捕获

try..catch..手动抛出错误方法来避免程序遇到错误终止执行

  1. //try正常执行没有错误的时候不走catch
  2. try {
  3. console.log('正常执行1');
  4. console.log(a);
  5. console.log(b);
  6. console.log('正常执行2');
  7. //捕获
  8. } catch (e) {
  9. console.log(e); //'ReferenceError: a is not defined'
  10. //不管有错没错都会执行
  11. } finally {
  12. console.log('正常执行3');
  13. }
  14. console.log('正常执行4');
  15. //正常执行1
  16. //'ReferenceError: a is not defined'
  17. //正常执行3
  18. //正常执行4

案例:

  1. //JSON字符串
  2. var jsonStr = '';
  3. try {
  4. console.log('我要执行了!');
  5. var json = JSON.parse(jsonStr);
  6. console.log(json);
  7. } catch (e) {
  8. var errorTip = {
  9. name: '数据传输失败',
  10. errorCode: '10010'
  11. }
  12. console.log(errorTip);
  13. //{name: "数据传输失败", errorCode: "10010"}
  14. }

throw

  1. //JSON字符串
  2. var jsonStr = '';
  3. try {
  4. if (jsonStr == '') {
  5. throw 'JSON字符串为空';
  6. }
  7. console.log('我要执行了!');
  8. var json = JSON.parse(jsonStr);
  9. console.log(json);
  10. } catch (e) {
  11. console.log(e); //JSON字符串为空
  12. var errorTip = {
  13. name: '数据传输失败',
  14. errorCode: '10010'
  15. }
  16. console.log(errorTip);
  17. //{name: "数据传输失败", errorCode: "10010"}
  18. }

垃圾回收

垃圾回收原理:

  1. 找出不再使用的变量
  2. 释放其占用内存
  3. 固定的时间间隔运行
  1. //标记清除: mark and sweep
  2. function test() {
  3. var a = 0; //进入环境
  4. }
  5. test(); //a 标记为 离开环境
  6. //引用计数 reference counting
  7. //次数为0 回收
  8. function test() {
  9. var a = new Object(); //a = 1;
  10. var b = new Object(); //b = 1;
  11. var c = a; //a++ = 2
  12. var c = b; //a-- = 1
  13. //循环引用
  14. a.prop = b; //b = 2;
  15. b.prop = a; //b = 2;
  16. a = null;
  17. b = null;
  18. }