JavaScript

JS:轻量级的客户端脚本编程语言

书籍:

1.编程语言

HTML+CSS是标记语言。
编程语言是具备一定逻辑的,拥有自己的编程思想(面向对象编程[OOP],面向过程编程)

  • 面向对象
    • C++
    • JAVA
    • PHP
    • C#(.NET)
    • JS
  • 面向过程
    • C

2.目前的JS是基于NODE可以做服务器端程序,所以JS是全栈编程语言。

3.JS 学习

  • ECMAScript(ES): JS核心语法
  • DOM: document object model 文档对象模型,提供各种API(属性和方法),让JS可以获取或操作页面中的HTML元素(DOM和元素)
  • BOM: browser object model 浏览器对象模型,提供各种API,让JS操作浏览器

4.ECMAScript

它是JS语法规划,规定:JS中的变量、数据类型、语法规范、操作语句、设计模式等等

  • 版本
    • 1997 ES1.0
    • 1998 ES2.0
    • 1999 ES3.0(广泛应用)
    • 2000 ES4(夭折)
    • 2015/6 ES6

变量(varibale)

它不是具体的值,只是一个用来存储具体值的容器或者代名词。存储的值可以改变,即变量。

基于ES语法规范,在JS中创建变量的方式

  • var (ES3)
  • function(ES3) 创建函数(函数名也是变量,只不过存储的值是函数类型)
  • let (ES6)
  • const (ES6) 创建的是常量
  • import (ES6) 基于ES6的模块规范导出需要的信息
  • class (ES6) 基于ES6创建类
  1. /* 语法:
  2. * var [变量名]=值;
  3. * let [变量名]=值;
  4. * const [变量名]=值;
  5. * function 函数名() {
  6. *
  7. * }
  8. * ...
  9. */
  10. var n = 13;
  11. n = 15;
  12. alert(n + 10);
  13. const m = 100;
  14. m = 150; // => Uncaught TypeError: Assignment to constant variable. 不能给一个常量重新赋值,常量存储的值不能被修改。

创建变量,命名的时候要遵循一些规范

  • 严格区分大小写
  1. var n = 12;
  2. var N = 13; //=> 两个N不是同一个变量
  • 遵循驼峰命名法:按照数字、字母、下划线或者$来命名,数字不能作为名字的开头,命名的时候基于英文单词组成一个完整的名字,第一个单词字母小写,其余每一个有意义的单词的首字母都大写。一般“ _ ” 在前的,都是公共变量,如: _studentInfo
  • 不能使用关键字和保留字

数据类型

数据值是一门编程语言进行生产的材料,JS中的数据类型:

  • 基本数据类型/值类型
    • 数字number
    • 字符串string
    • 布尔boolean
    • null
    • undefined
  • 引用数据类型
    • 对象object
      • 普通对象
      • 数组对象
      • 正则对象
      • 日期对象
    • 函数function
  • Symbol (唯一的值,ES6中新增加的一个特殊的类型)
  1. [基本数据类型]
  2. var n = 13; //=>0 -13 13.2 数字类型中有一个特殊的值NaN(not a number 表示不是一个有效的数字,但是属于number类型)
  3. var s = ''; //=> "" '13' “{}”,一个字符串由零到多个字符串组成
  4. var b = true; //=> 布尔 true真 flase假
  5. [引用数据类型]
  6. var o = {name: 'serendity',age: 10 }; //=> 普通对象:由大括号包括起来。里面包含多组属性名和属性值/包含多组键值对,{} 空对象
  7. var ary = [12,23,20, 21]; //=>数组对象:中括号包裹,包含零到多项内容 [] 空数组
  8. var reg = /-?(\d|([1-9]\d+))(\.\d+)?/g; //=>正则对象:由元字符组成一个完整的正则 。验证是否为有效数字 ;至少包含一个字符,没有空正则
  9. function fn() {
  10. }
  11. [Symbol] 创建出来的是一个唯一的值/没有其他的与它相等
  12. var a = Symbol(‘n’)
  13. var b = Symbol(‘n’)
  14. a===b // => false
  15. const a = Symbol(‘n’); // => 只是唯一的并且不可以被更改,用const声明。

扩展: JS代码如何被运行以及运行后如何输出结果

[如何被运行]

  • 把代码运行在浏览器中/浏览器内核来渲染解析
  • 基于NODE来运行/Node也是一个基于V8引擎渲染和解析JS的工具,注:node不是一种语言,是渲染JS的工具或平台。

[如何输出结果]

  • alert: 在浏览器中通过弹窗的方式输出/浏览器提示框
  1. window.alert();
  2. alert(1+1); // => '2',基于alert输出的结果都会转换为字符串:把值(如果是表达式先计算出结果)通过toString这个方法转换为字符串,然后输出
  3. alert(true); // => 'true'
  4. // alert({name:'xxx'}); => '[object object]'
  5. // {name:'xxx'}.toString =>'[object object]' 为什么?
  6. // 对象.toString后的结果是object object.
  • confirm: 和alert的用法一致。只不过提示框中有确定和取消两个按钮。 即确认提示框。
  1. var flag = confirm('确定要退出吗?');
  2. if(flag){
  3. //=>flag:true 用户点击确定
  4. }else {
  5. //=>flag:flase 用户点击取消
  6. }
  • prompt: 在confirm的基础上增加输入框 点击取消 输出null, 确定 输出空字符串
  • console.log: 在浏览器控制台输出日志
    • Elements
    • Console: 控制台
    • Sources: 网站源文件
  • console.dir: 比log输出的更加详细一些,尤其输出对象数据值时
  • console.table: 把JSON数据按照表格的方式输出
  • …更多console输出方法

数据类型的详细刨析

number 数字类型

  1. number 数字类型

NaN : not a number 但是它是数字类型的
isNaN: 检测当前的值是否不是有效数字 返回 true 表示不是有效数字,flase 是有效数字

  1. // = > isNaN ([value])
  2. var num = 12
  3. isNaN(num); // = > 检测 num 变量存储的值是否为有效数字 flase
  4. isNaN('13'); = > false
  5. isNaN('num'); = > true
  6. isNaN(true); = > false
  7. isNaN(false); = > false
  8. isNaN(undefined); = > true
  9. isNaN({age:'9'}); = > true
  10. isNaN([12,23]); = > true
  11. isNaN([12]); = > false
  12. isNaN(/^$/); = > true
  13. isNaN(function() {}); = > true
  14. /*
  15. 重要: isNaN 检测机制
  16. 1. 首先验证当前值是否为数字类型,如果不是浏览器默认把值转换为数字类型
  17. 把非数字类型转换为数字
  18. - 其他数字类型转换位数字: 使用 Number 方法转换
  19. [字符串转数字]
  20. Number('13') -> 13
  21. Number('13px') -> NaN 如果字符串出现任意一个非有效数字的字符 结果则为 NaN
  22. Number('13.5') -> 13.5
  23. Number('13.5.0') -> NaN
  24. [布尔转数字]
  25. Number(true) -> 1
  26. Number(false) -> 0
  27. [其他]
  28. Number(null) -> 0
  29. Number(undefined) -> NaN
  30. - 把引用数据类型转换为数字: 先把引用值调取 toString 转换为字符串,然后再把字符串调取 Number 转换为数字。
  31. [对像转数字]
  32. 所有对象 toString() => '[object object]'
  33. ({})).toString() -> '[object object]' - > NaN
  34. [数组转数字]
  35. ([12,23]).toString() -> '12,23' - > NaN
  36. ([12]).toString() -> '12' - > 12
  37. [函数转数字]
  38. (function() {}).toString() -> "function() {}" -> NaN
  39. [正则]
  40. /^$/.toString() -> '/^$/' - > NaN
  41. Number('') - > 0
  42. [].toString() -> ''=> isNaN([]) => false
  43. 2. 当前值已经是数字类型,是有效数字返回 false,不是返回 true (数字类型中 只有 NaN 不是有效数字 其余都是有效数字)
  44. */
  1. parseInt / parseFloat

等同于 Number ,也是为了把其他类型的值转换为数字类型
和 Number 区别在于字符串的转换分析
Number: 出现任意非有效数字字符 结果就是 NaN;
parseInt: 把一个字符串中的整数部分解析出来
parseFloat:把一个字符串中的小数(浮点数)部分解析出来

  1. parseInt('13.5px') => 13
  2. parseFloat('13.5px') = > 13.5
  3. parseInt('width:13.5px') => NaN 从字符串最左边字符串开始查找有效数字字符并且转换为数字,一旦遇到一个非有效数字字符,查找结束。
  1. NaN 的比较

NaN: 不是一个数,可以是其他任何东西

  1. NaN == NaN => false NaN 和谁都不相等 包括自己
  2. 思考: 有一个变量 num ;存储的值不知道,检测是否为一个有效数字,一下方案是否可以
  3. if(Number(num) == NaN) {
  4. alert('不是')
  5. }
  6. NaN 和谁都不相等,假设 num 不是有效数字,=> NaN; 此条件永远不成立,即使 num 确实不是有效数字。
  7. // 有效数字 检测只有这一种方案
  8. if(isNaN(num)) { // true 不是有效数字
  9. alert('不是')
  10. }

布尔类型

只有两个值: true / false

  1. 如何把其他数据类型转换为布尔类型?
  • Boolan(); 数字中除了 0 和 NaN 是 false 其他都是 true
  • !
  • !!
  1. Boolean(1) = > true
  2. Boolean(0) = > false
  3. Boolean(-1) = > true
  4. Boolean(NaN) = > false
  5. !'Serendipity' // 先把其他数据类型转换为布尔类型 然后取反 !true => false
  6. !!'' // 先把其他数据类型转换为布尔类型 然后取两次反,等价于没取反,即剩下布尔值 => false

规律: 在 JS 中只有“ 0 / NaN / 空字符串 / null / undefined ”这五个值转换为布尔类型为 false,其余都转换为 true

null 和 undefined

null 和 undefined 都代表空或没有

  • null: 空对象指针
  • undefined: 未定义
  1. null 和 undefined 的区别
  • null: 一般独使意料之中的没有一般都是手动的先赋值为 null,后面程序会再次赋值
  • undefined: 意料之外的没有,一般都不是人为手动控制,大部分都是浏览器自主为空,后面赋值也可以不赋值

Object 对象数据类型

普通对象

  • 由大括号包裹起来
  • 由零到多组属性名和属性值(键值对)组成

属性是用来描述当前对像特征的,属性名是对当前具备这个特征,属性值是对这个特征的描述(专业语法:属性名称为键[key],属性值称为值[value],一组属性名和属性值称为一组键值对)

  1. var obj = {
  2. name: 'serendipity'
  3. age: 9
  4. }
  5. // => 对象的操作: 对键值对的增删改查
  6. [获取]
  7. 语法: 对象.属性名 / 对象[属性名]
  8. obj.name
  9. obj['name'] 一般来说,对象的属性名都是字符串格式的。(属性值不固定,任何格式都可以)
  10. [增/改]
  11. JS的一个对象中属性名是唯一的,不允许重复
  12. 语法:对象.属性名 = xxx / 对象[属性名] = xxx
  13. obj.name = '某某某某' // => 原有对象中存在 name 属性,此处属于修改属性值
  14. obj.sex = '男' // => 原有对象中不存在 sex 属性,此处属于增加属性
  15. obj['age'] = 23;
  16. [删]
  17. 彻底删除:对象中不存在这个属性
  18. delete obj['age'];
  19. 假删除:并没有移除这个属性,只是让当前的属性值为空
  20. obj.sex = null;
  21. 在获取属性值的时候,如果当前对象有这个属性名,则可以获取到值(哪怕是 null ),如果当前对象有这个属性名,则可以获取到值(哪怕是 null )如果当前对象没有有这个属性名,则获取结果是 undefined;
  1. 思考题:
  2. var obj = {
  3. name: 'serendipity'
  4. age: 9
  5. };
  6. var name = 'cherish';
  7. obj.name = > serendipity 获取的是 name 属性的值
  8. obj['name'] = > serendipity 获取的是 name 属性的值
  9. obj.[name] = > undefined 此处的 name 是一个变量 我们获取的属性名不叫做 name ,是 name 存储的值 cherish’,
  10. obj['cherish'] = > 没有这个属性 undefined
  11. ----
  12. 'name' name 的区别
  13. = > 'name' 是一个字符串值 代表的是本身
  14. = > name 是一个变量 不是值 代表本身存储的这个值

[一个对象中的属性名不仅仅是字符串格式,还可能是数字格式的。遇到]

  1. var obj = {
  2. name: 'serendipity'
  3. 0: 100
  4. }
  5. obj[0] => 100
  6. obj['0'] => 100
  7. obj.0 => 报错 SyntaxError 语法错误
  8. ----
  9. 当我们存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转换为字符串(toString),然后再进行存储
  10. obj.[{}] = 300; => 先把 ({}).toString() 后的结果作为对象的属性名存储起来 obj.['[object object]'] = 300;
  11. // 获取的时候
  12. obj.[{}]; => 获取的时候也是先把对象转化为字符串'[object object]' ,然后获取之前存储的 300;
  13. obj[1] '1': 100
  14. ----
  15. 数组对象(对象由键值对组成)
  16. var oo = {
  17. a : 12;
  18. }
  19. // 数组也是对象
  20. var arr = [12,23] // 12 和 23 都是属性值,属性名呢?
  21. 通过观察结果: 数组对象的属性名是数字,(我们把数字属性名称为当前对象的索引)
  22. arr[0] => 12;
  23. arr['0'] => 12;
  24. arr.0 => 报错 SyntaxError 语法错误
  25. arr.length
  26. arr['length']
  27. [],的语法不支持直接添加属性名 如:[age:12]

数组也是对象,对象所拥有的操作,都可以运用到数组,可以添加非数字索引,数组的索引也是属性名,但是比较特殊可以递增。所有的对象 object 都可以运用对象的操作 函数也是对象

浅分析 JS 的运行机制

  1. var a = 12;
  2. var b = a;
  3. b = 13;
  4. console.log(a); // => 12
  5. var obj1 = {n: 100}
  6. var obj2 = obj1;
  7. obj2['n'] = 200;
  8. console.log(obj1.n); // => 200
  9. /**
  10. * 浅分析 JS 运行机制
  11. * 1.当浏览器(他的内核 / 引擎)渲染和解析 js 的时候,会提供一个供 js 代码运行的环境我们把这个环境称为全局作用域(global/windowscope)
  12. *
  13. * 2.代码自上而下执行(之前还有一个变量提升阶段)
  14. * = > 基本数据类型的值会存储再当前作用域下
  15. * var a = 12 ;
  16. * 1)首先开辟一个空间(栈内存空间)存储 12
  17. * 2)在当前作用域中声明一个变量 a
  18. * 3)让声明的变量和存储的 12 进行关联(把存储的 12 赋值给 a =>赋值操作叫做定义)
  19. *
  20. * - > 基本数据类型值(值类型),是按照值来操作的:把原有的值复制一份放到新的空间或位置上,和原来的值没有关系
  21. *
  22. * = > 引用数据类型的值不能直接存储到当前的作用域下(因为可能存储的内容过去复杂),需要先开辟一个新的空间(理解为仓库),把内容存储到这个空间中。
  23. * var obj = {n: 100};
  24. * 1) 首先开辟一个新的内存空间(堆内存空间),把对象中的键值对依次存储(为了保证后面查找该空间,此空间有一个 16 进制的地址)
  25. * 2)声明一个变量
  26. * 3)让变量和空间地址关联一起(把空间地址赋值给变量)
  27. *
  28. * - > 引用类型不是按照值来操作,它操作的是空间的引用地址:把原来空间的地址赋值给新的变量,但是原来的空间没有被克隆,还是一个空间,这样就会出现多个变量关联的是相同的空间,相互之间存在影响。
  29. *
  30. * 栈内存 和 堆内存
  31. *
  32. * 栈内存:提供一个代码运行的环境 本身就是代码运行的环境,所有的基本类型值都会在栈内存中开辟一个对应的位置进行存储。
  33. *
  34. * 堆内存:独立,用来存储引用类型中的信息值(对象存储的是键值对,函数存储的是代码字符串)
  35. *
  36. */

[ 堆栈练习 ]

  1. var obj = {
  2. n: 10,
  3. m: obj.n * 10
  4. // property 'n' of undefined 报错
  5. }
  6. console.log(obj.m);
  7. /**
  8. * 1. 形成一个全局作用域
  9. * 2. 代码自上而下执行
  10. * 1.首先开辟一个堆内存,把键值对存储到堆内存中,
  11. * n: 10,
  12. m: obj.n * 10 = > obj.n 此时堆内存还没有存储完成,空间地址还没有给 obj ,此时的 obj 是 undefined,
  13. obj.n <=> undefined.n
  14. undefined 是基本数据类型 没有属性,故报错 Uncaught TypeError: Cannot read property 'n' of undefined
  15. at 2.js:15
  16. *
  17. */
  18. var ary1 = [3,4];
  19. var ary2 = ary1;
  20. ary2[0] = 1;
  21. ary2 = [4,5];
  22. ary2[1] = 2;
  23. arr[1] = 0;
  24. console.log(ary1,ar2); // => 1,0 4,2

JS 中的操作语句

判断语句

  1. if / else if / else
  2. if / else if / else