JavaScript
一、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:bbrowser object model 浏览器对象模型,提供各种API让JS可以操作浏览器
二、ESMAScript
它是JS的语法规定,JS中的变量、数据类型、语法规范、操作语句、设计模式等等都是ES规定的
三、变量(variable)
它不是具体的值,只是一个用来存储具体值的容器或者代名词,因为它存储的值可以改变,所以成为变量。
基于ES语法规范,在JS创建变量有以下方式
- var (ES3)
- function(ES3)创建函数(函数也是变量,只不过存储的值是函数类型的而已)
- let(ES6)
- const(ES6)创建的是常量
- import(ES6)基于ES6的模块规范导出需要的信息
- class(ES6)基于ES6创建类
/*
* 语法:
* var [变量名] = 值;
* let [变量名] = 值;
* const [变量名] = 值;
* function 函数名 () {
* }
* ...
*/
var n = 13;
n = 15;
alert(n+10); //=>弹出来25 此时的N代表15
const m = 100;
m = 200; //=>Uncaught TypeError: Assignment to constant variable.不能给一个常量重新赋值(常量存储的值不能被修改,能够修改的是变量)
创建变量,命名的时候要遵循一些规范
-严格区分大小写
-遵循驼峰命名法:按照数字、字母、下划线来命名(数字不能作为名字的开头),命名的时候基于英文单词拼接成一个完整的名字(第一个单词字母小写,其余每一个有意义单词的首字母都大写)
-不能使用关键字和保留字:在JS中有特殊含义的叫做关键字,未来可能会成为关键字的叫做保留字。
var n=12;
var N=13; //=>两个n不是同一个变量
var studentInfo / student_info / _stufentInfo(下划线在前的,都是公共变量) / $studentInfo(一般存储的是JQ元素)...
语义化强一些
add / create / insert
del(delete) / update / remove(rn)
info / detail
log
...
四、数据值是一门编程语言进行生产的材料,JS中包含的值有以下这些类型
- 基本数据类型(值类型)
- 数字Number
- 字符串String
- 布尔Boolean
- null
- undefined
- 引用数据类型
- 对象Object
- 普通对象
- 数组对象
- 正则对象
- 日期对象
- …
- 函数function
- 对象Object
- ES6中新增加的一个特殊的类型:Symbol。唯一的值
[基本数据类型]
var n=13; //=>0 -13 13.2 数字类型中有一个特殊的值NAN(not a number 代表不是一个有效的数字,但是属于number类型)
var s='' //=>"" '13' "{}" JS中所有用单引号或者双引号包裹起来的都是字符串,里面的内容是当前字符串中的字符(一个字符串由零到多个字符组成)
var b=true //=>布尔类型只有两个值 true真 false假
[引用数据类型]
var o = {name: 'ANote', age: 18} //=>普通的对象:由大括号包裹起来,里面包含多组属性名和属性值(包含多组键值对) {}空对象
var ary = [12, 23, 34, 45] //=>中括号包裹起来,包含零到多项内容。这种是数组对象 []空数组
var reg = /-?(\d|([1-9]\d+))(\.\d+)?/g; //=>有元字符组成一个完整的正则 //不是空正则是单行注释
function fn() { //=>函数
}
[Symbol]
创建出来的是一个唯一的值
var a = Symbol('ANotes');
var b = Symbol('ANotes');
a==b =>false
扩展:JS代码如何被运行以及运行后如何输出结果
[如何被运行]
- 把代码运行在浏览器中(浏览器内核来渲染解析)
- 基于NODE来运行(NODE也是一个基于V8引擎渲染和解析JS的工具)
[如何输出结果]
- alert:在浏览器中通过弹框的方式输出(浏览器提示框)
var num=12;
alert(num); //=>window.alert
var str='ANotes';
alert(str);
基于alert输出的结果都会转换为字符串,把值(如果是表达式先计算出结果)通过toString这个方法转换为字符串,然后在输出。
alter(1+1); =>'2'
alert(true); =>'true'
alert([12,23]); =>'12,23'
alert({name: 'xxx'}); =>'[object object]' 对象toString后的结果就是object object,为啥?
- comfirm:和alert的用法一致,只不过提示的框中有确定和取消两个按钮,所以它是确认提示框。
var flag = confirm('确定要退出吗?');
if(flag) {
//=>flag:true 用户点击的是确定按钮
} else {
//=>flag:false 用户点击的是取消按钮
}
-
prompt:在confirm的基础上增加输入框
-
console.log: 在浏览器控制台输出日志(按F12(FN+F12)打开浏览器的控制台)
- Elements:当前页面中的元素和样式在这里都可以看到,还可以调样式修改结构等;
- Console:控制台,可以JS代码中通过.log输出到这里,也可以在这里直接的编写JS代码;
- Sources:当前网站的源文件都在这里;
- …
-
console.dir:比log输出的更加详细一些(尤其是输出对象数据值的时候);
-
console.table:把一个JSON数据按照表格的方式输出;
-
…(拓展更多console输出方法)
五、数据类型的详细解剖
- number数字类型
NaN:not a number 但是它是数据类型的
isNaN:检查当前这个值是否不是有效数字,返回true代表不是有效数字,返回false是有效数字;
//=>语法:isNaN([value])
var num=12;
isNaN(num); //=>检查num变量存储的值是否为非有效数字 false
isNaN('13'); //=> false
isNaN('ANotes'); //=> true
isNaN(true); //=> false
isNaN(false); //=> false
isNaN(null); //=> false
isNaN(undefind); //=> true
isNaN({age:9}); //=> true
isNaN([12, 23]) //=> true
isNaN([12]); //=> false
isNaN(/^$/); //=> true
isNaN(function() {}); //=> true
重要:isNaN检测的机制
1、首先验证当前要检测的值是否为数字类型,如果不是,浏览器会默认的把值转换为数字类型;
把非数字类型的值转换为数字
- 其它基本类型转化为数字:直接使用Number这个方法转换的
[字符串转数字]
Number('13'); -> 13
Number('13px'); -> NaN 如果当前字符串出现任意一个非有效数字字符,结果则为NaN;
Number('13.5'); -> 13.5
[布尔值转数字]
Number(true); -> 1
Number(false); -> 0
[其他]
Number(null); -> 0
Number(undefined); -> NaN
-引用数据类型值转换为数字:先把引用值调取toString转换为字符串,然后再把字符串调取Number转换为数字;
[对象]
({}).toString() ->'[object object]' ->NaN
[数组]
[12, 23].toString() ->'12,23' ->NaN
[12].toString() ->'12' -> 12
[正则]
/^$/.toString() ->'/^$/' ->NaN
Number(''); ->0
[].toString(); ->''
=> isNaN([]); -> false
2、当前检测的值已经是数字类型,是有效数字返回false,不是返回true(数字类型中只有NaN不是有效数字,其余都是有效数字);
- parseInnt / parseFloat
等同于Number,也是为了把其它类型的值转换为数字类型;
和Number的区别在于字符串转换分析上;
Number:出现任意非有效数字字符,结果就是NaN;
parseInt:把一个字符串中的整数部分解析出来,parseFloat是把一个字符串中小数(浮点数)部分解析出来;
parseInt('13.5px') -> 13
parseFloat('13.5px') -> 13.5
parseInt('width:13.5px') -> NaN 从字符串最左边字符开始查找有效数字字符,并且转换为数字,但是一旦遇到一个非有效数字字符,查询结束;
- NaN的比较
NaN==NaN: false NaN和谁都不相等,包括自己;
思考题:有个变量num,存储的值不知道,我想检测它是否为一个有效数字,一下方案是否可以?
if (Number(num) == NaN) {\
alert('num不是有效数字!');
}
NaN和谁都不相等,条件永远不成立(即使num确实不是有效数字。转换的结果确实是NaN,但是NaN!=NaN的);
if (isNaN(num)){
//=>检查是否为有效数字,只有一个方案
alert('num不是有效数字!');
}
isNaN(NaN); ->true
六、布尔类型
只有两个值:true / false
如何把其它数据类型转换为布尔类型?
- Boolean
- !
- !!
Boolean(1); =>true
!'ANotes' =>先把其它数据类型转换为布尔类型,然后取反;
!!null => 取两次反,等于没去反,也就剩下转换为布尔值类型了;
规律:在JS中只有"0 / NaN / 空字符串 / null / undefined" 这五个字值转换为布尔类型的false,其余都是转换为true
null & undefined 都代表空或者没有
- null:空对象指针;
- undefined:未定义;
null:一般都是意料之中的没有(通俗理解:一般都是认为手动的先赋值为null,后面的程序中我们会再次给它赋值);
var num = null; //=> null是手动赋值,预示着后面我会把num变量的值进行修改;
...
num = 12;
undefind:代表的没有,一般都不是人为手动控制的,大部分都是浏览器自主为空(后面可以赋值也可以不赋值);
var num; //=> 此时变量的值,浏览器给分配的就是undefined
...
后面可以赋值也可以不赋值
七、Object对象数据类型
普通对象
- 由大括号包裹起来的
- 由零到多组属性名和属性值(键值对)组成
属性是用来当前对象特征的,属性名是当前具备这个特征,属性值是对这个特征的描述(专业语法,属性名称为键[key],属性值称为值[value],一组属性名和属性值称为一组键值对)
var obj = {
name: 'ANotes',
age: 9
};
//=>对象的操作,对键值对的增删改查
[获取]
语法:对象.属性名 / 对象[属性]
obj.name
obj['name'] 一般来说,对象的属性名都是字符串格式的(属性值不固定,任何格式都可以)
[增/改]
JS对象中,属性名不予许重复的,是唯一的。
obj.name = '哈哈'; //=>原有对象中存在NAME属性,此处属于修改属性值。
obj.sex = '男'; //=>原有对象中不存在SEX,此处相当与给当前对象新增一个属性SEX
[删]
彻底删除:对象中不存在这个属性了。
delete obj['age'];
假删除:并没有移除这个属性,只是让当前属性的值为空。
obj.sex = null;
在获取属性值的时候,如果当前对象有这个属性名,则可以正常获取到值(哪怕是null),但是如果没有这个属性名,则获取的结果是undefined。
obj['friends'] =>undefined
思考题:
var obj = {
name: 'ANotes',
age: 9
};
var name = 'mine';
obj.name //=>'ANotes' 获取的是NAME属性的值;
obj['name'] //=>'ANotes' 获取的是NAME属性的值;
obj[name] //=>此处的NAME是一个变量,我们要获取的属性名不叫做NAME,是NAME存储的值'nime'
=>obj['mine'] =>没有这个属性,属性值是undefined;
----
'name' 和 name 的区别?
=>'name'是一个字符串值,它代表的是本身
=>name是一个变量不是值,它代表的是本身存储的这个值
一个对象中的属性名不仅是字符串格式的,还有可能是数字格式的
var obj = {
name = 'ANotes',
0: 100
}
obj[0] => 100
obj['0'] => 100
obj.0 => Uncaught SyntaxError: Unexpected number
----
当存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转化为字符串(toString),然后再进行存储
obj[{}] = 300; =>先把({}).toString()后的结果作为对象的属性名存储jinl进来 obj['[object Object]'] = 300,
obj[{}] =>获取的时候也是先把对象转换为字符串'[object Object]',然后获取之前存储的值(300)。
----
数组对象(对象石油键值对组成的)
var oo = {
a = 12
};
var ary = [12, 23] //=>12和23都是属性值,属性名呢?
通过观察结果,我们发现数组对象的属性名是数字(我们把数字属性名称为当前对象的索引)
ary[0]
ary['0']
ary.0 => Uncaught SyntaxError: Unexpected number
示例
var a = 12;
var b = a;
b = 13;
console.log(a); //=> 12
var obj = {n : 100};
var obj1 = obj;
obj1['n'] = 200;
console.log(obj.n); //=> 200
/**
* 浅分析JS的运行机制
* 1、当浏览器(他的内核/引擎)渲染和解析JS的时候,会提供一个供JS代码运行的环境,我们把这个环境称之为“全局作用域(global/window scope)”
* 2、代码自上而下执行(之前还有一个变量提升阶段)
* =>基本数据类型的值会存储在当前作用域下
* var a = 12;
* 1)首先开辟一个空间存储12;
* 2)在当前作用域中声明声明一个变量a(var a);
* 3)让声明的变量和存储的12进行关联(把存储的12赋值给a =>赋值操作叫做定义);
*
* 基本数据类型值(也叫作值类型),是按照值来操作的:把原有的值复制一份放到新的空间或者位置上,和原来的值没有关系;
* =>引用数据类型的值不能直接存储到当前的作用域下(因为可能存储的内容过于复杂),我们需要先开辟一个新的空间(理解为仓库),把内容存储到这个空间中
* var obj = {n : 100};
* 1)首先开辟一个新的内存空间,把对象中的键值对依次存储起来(为了保证后面可以找到这个空间,此空间有一个16进制的地址)
* 2)声明一个变量
* 3)让变量和空间地址关联在一起(把空间地址赋值给变量
*
* 引用数据类型不是按照值来操作,它操作的是空间的引用地址:把原来的地址赋值给新的变量,但是原来的空间没有被克隆,还是一个空间,这样就会出现多个变量关联的是相同的空间,相互之间就会存在影响了。
*
* 栈内存:本身就是一个提供JS代码执行的环境,所有的基本类型都会直接的在栈内存空间开辟一个位置进行存储
* 堆内存:用来存储引用类型中的信息值的
* 对象存储的是键值对
* 函数存储的是代码字符串
*/