● JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(Script 是脚本的意思)
● 脚本语言:不需要编译,运行过程中→js解释器(js 引擎)逐行来进行解释并执行
● 现在也可以基于Node.js 技术进行服务器端编程
● 表单动态检验(密码强度检测)(JS 产生的最初目的)
● 网页特效
● 服务端开发(Node.js)
● 桌面程序(Electron)
● APP(Cordova)
● 控制硬件-物联网(Ruff)
● 游戏开发(cocos2d-js)
HTML/CSS 标记语言——描述类语言
● HTML 决定网页结构和内容(决定看到什么)
● CSS 决定网页呈现给用户的模样(决定好不好看)
JS脚本语言——编程类语言
● 实现业务逻辑和页面控制(决定功能),相当于人的各种动作
浏览器分为两部分:渲染引擎和JS引擎
● 渲染引擎:用来解析HTML与CSS,俗称内核,比如 Chrome 浏览器的 blink ,老版本的 webkit
● JS 引擎:也称为 JS 解释器。用来读取网页中的JavaScript 代码,对其处理后运行,比如 Chrome 浏览器的V8
浏览器本身并不会执行JS代码,而是通过内置JavaScript引擎(解释器)来执行JS代码。JS 引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以JavaScrip语言归为脚本语言,会逐行解释执行。
● ECMAScript (JavaScript 语法)
● DOM (页面文档对象模型)
● BOM(浏览器对象模型)
ECMAScript 是由ECMA 国际(原欧洲计算机制造商协会)进行标准化的一门编程语言,这种语言在万维网上应用广泛,它往往被称为 JavaScript(网景公司) 或 JScript(微软公司),但实际上后两者是ECMAScript 语言的实现和扩展。
EMCAScript :EMCAScript 规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一台JS语法工业标准。
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展的标记语言的标准编程接口。通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。
BOM(Brower Object Model,简称BOM)是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
JS 有3种书写体验,分别为行内、内嵌和外部。
● 行内式的js 直接写到元素的内部
● 内嵌和css相似,css写在里,js 写在
● 可以将单行或少量JS 代码写在HTML标签的事件属性中(以 on开头的属性),如:onclick
● 注意单双引号的使用:在HTML中我们推荐使用双引号,JS中我们推荐使用单引号
● 可读性差,在HTML中编写JS大量代码,不方便阅读
● 引号易错,引号多层嵌套匹配时,非常容易弄混
● 特殊情况下使用
● 可以将多行 JS代码写到
● 利于HTML页面代码结构化,把大段 JS 代码独立到HTML页面之外,既美观,也方便文件级别的复用
● 引用外部 JS文件的script 标签中间不可以写代码
● 适合于JS代码量比较大的情况
常用语句:
方法 说明 归属
alert(msg) 浏览器弹出警示框 浏览器
console.log(msg) 浏览器控制台打印输出信息 浏览器
prompt(info) 浏览器弹出输入框,用户可以输入 浏览器
● 什么是变量?
变量就是一个装东西的盒子
变量是用于存放数据的容器,我们通过变量名获取数据,甚至数据可以修改。
● 变量在内存中的存储
本质:变量是内存中申请的一块用来存放数据的空间
变量使用时分成两步:1. 声明变量 2. 赋值
1. 声明变量
//声明变量
var age; //声明一个名称为age的变量
let 变量名//let是后面ES的语法 现在直接用着
● var 是一个JS 关键字,用来声明变量(variable 变量的意思)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管
● age 是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间
var声明:
● 可以先使用再声明(不合理)
● var声明过的变量可以重复声明(不合理)
● 比如变量提升、全局变量、没有块级作用域
2. 赋值
age = 10; //给 age 这个变量赋值为10
● = 用来把右边的值赋给左边的变量空间中,此处代表赋值的意思
● 变量值是程序员保存到变量空间里的值
3. 变量的初始化
var age = 18; //声明变量同时赋值为18
声明一个变量并开始赋值,我们称之为变量的初始化
1. 更新变量
一个变量被重新赋值后,它原有的值就会被覆盖,变量值将以最后一次为准。
2. 同时声明多个变量
var age = 18,
address = ‘火影村’,
salary = 2000;
3. 声明变量特殊情况
情况 | 说明 | 结果 |
---|---|---|
var age; console.log (age); | 只声明 不赋值 | undefined 未定义的 |
console.log (age); | 不声明 不赋值 直接使用 | 报错 |
age = 10; console.log (age); | 不声明 只赋值 | 10 |
● 由字母(A-Z a-z)、数字(0-9)、下划线、美元符号$组成,如:usrAge,num01,name
● 严格区分大小写。 var app 和var APP是两个变量
● 不能以数字开头。18age 是错误的
● 不能是关键字、保留字。例如:var, for ,while
● 变量名必须有意义。 MMD BBD nl
● 遵守驼峰命名法。首字母小写,后面单词的首字母需大写 myFirstName
● 推荐翻译网站 有道 爱词霸
name是特殊含义的 不直接使用作为变量名
数组是一种顺序保存数据的
1. 声明语法
let 数组名 = [数据1,数据2,数据……]
数组可以存储任意类型的数据
2. 取值语法
[数组名]下标
3. 一些术语:
● 元素:数组中保存的每个数据都叫数组元素
● 下标:数组中数据的编号
● 长度:数组中数据的个数,通过数组的length属性获得
数组.push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度
arr.push(元素1,…,元素n)
数组.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度
数组.pop()方法从数组中删除最后一个元素,并返回该元素的值
语法:arr.pop()
数组.pop()方法从数组中删除第一个元素,并返回该元素的值
语法:arr.shift()
arr.splice()删除指定元素
语法:
● arr.splice(start, deleteCount)
● start起始位置:
○ 指定修改的开始位置(从0开始计数)
● deleteCount:
○ 表示要移除的数组元素的个数
○ 可选的。如果省略则默认从指定的起始位置删除到最后
使用场景:
后期课程我们会用到删除操作,特别是splice
基本数据类型和引用数据类型
正数、负数、小数等 统一称为数字类型。
注:JS是弱数据类型,变量到底属于哪种类型,只有赋值之后才能确认
JAVA是强数据类型 例如int a = 3,必须是整数
通过单引号‘’ 双引号“” 或 反引号 ``包裹的数据都叫字符串,单引号和反引号没有本质上的区别,推荐使用单引号。
注:
模板字符串:
作用:
○ 拼接字符串和变量
○ document.write('hello'+name+',,');
符号:
○ ``
○ 在英文输入模式下按tab键上方那个键
○ 内容拼接变量时,用${}包住变量
○ document.write('hello,my name is ${name},');
true真 false假
未定义是比较特殊的类型,只有一个值undefined。
什么情况出现未定义类型?
只声明变量,不赋值的情况下,变量的默认值为undefined,一般很少直接为某个变量赋值为undefined。
工作中的使用场景:
我们开发中经常声明一个变量,等待传送过来的数据。
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传送过来。
情况 | 说明 | 结果 |
---|---|---|
let age;console.log(age) | 只声明 不赋值 | undefined |
console.log(age) | 不声明 不赋值 直接使用 | 报错 |
age = 10;console.log(age) | 不声明 只赋值 | 10(不提倡) |
null 表示 值为空
null和undefined区别:
● undefined表示没有赋值
● null表示赋值了,但是内容为空
null开发中的使用场景:
官方解释:把null作为尚未创建的对象
通俗:将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
数字型和布尔型颜色为蓝色,字符串和undefined颜色为灰色
let age = 18
console.log(typeof age)//number
JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
规则:
● + 号两边只要有一个是字符串,都会把另外一个转成字符串
● 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型
缺点:
● 转换类型不明确,靠经验才能总结
小技巧:
● +号作为正号解析可以转换成Number
console.log(typeof ‘123’)//string
console.log(typeof +‘123’)//number
console.log(+‘11’ + 11)//22
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。
为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
概念:自己写代码告诉系统该转成什么类型
转换为数字型
● Number(数据)
○ 转成数字类型
○ 如果字符串内容里有非数字,转换失败时结果为 NaN(Not a Number)即不是一个数字
○ NaN也是number类型的数据,代表非数字
● parseInt(数据)
○ 只保留整数
● parseFloat(数据)
○ 可以保留小数
转换为字符型:
● String(数据)
● 变量.toString(进制)
用户订单案例:利用document.write()打印表格,所用变量要${}
数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)。
● +:求和
● -:求差
● *:求积
● /:求商
● %:取模(取余数)
○ 开发中经常作为某个数字是否被整除
同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。
JavaScript中 优先级越高越先被执行,优先级相同时以书从左向右执行。
● 乘、除、取余优先级相同
● 加、减优先级相同
● 乘、除、取余优先级大于加、减
● 使用 () 可以提升优先级
总结: 先乘除后加减,有括号先算括号里面的(和实际数学运算一样)
● 赋值运算符:对变量进行赋值的运算符
○ 已经学过的赋值运算符:= 将等号右边的值赋予给左边, 要求左边必须是一个容器
○ 其他赋值运算符
■ +=
■ -=
■ *=
■ /=
■ %=
● 使用这些运算符可以在对变量赋值时进行快速操作
let num = 1;
num += 1;//num = num + 1
num += 3;//num = num + 3
众多的 JavaScript 的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符
● 二元运算符
○ 例:let num = 1+3
● 一元运算符
○ 例:正负号
● 自增++ 有前置自增++num 和 后置自增num++
● 自减–
● 使用场景:经常用于计数来使用。 比如进行10次操作,用它来计算进行了多少次了
自增运算符的用法:
● 前置自增和后置自增单独使用没有区别
● 如果参与运算的话有区别:
○ 前置自增:先自加再使用(记忆口诀:++在前 先加)
○ 后置自增:先使用再自加(记忆口诀:++在后 后加)
let i = 1;
console.log(++i + 2);//4
console.log(i++ + 2);//3
● 一般开发中我们都是独立使用
● 后面 i++ 后置自增会使用相对较多
作用:
使用:
细节:
总结:
使用:
符号 | 名称 | 特点 | 口诀 |
---|---|---|---|
&& | 逻辑与 | 符号两边都为true结果才为true | 一假则假 |
|| | 逻辑或 | 符号两边有一个true就为true | 一真则真 |
! | 逻辑非 | true变false | 真变假,假变真 |
逻辑运算符的短路:
短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行
原因:通过左边能得到整个式子的结果,因此没必要再判断右边
表达式:
语句:
区别:
其实某些情况,也可以把表达式理解为语句,因为它是在计算结果,也是做事
1. 程序三大流程控制语句
2. 分支语句
分支语句可以让我们有选择性的执行想要的代码
分支语句包含:
if语句有三种使用:单分支、双分支、多分支
其实是比 if 双分支 更简单的写法,有时候也叫做三元表达式
符号:? 与 : 配合使用
语法:`条件?满足条件执行的代码: 不满足条件执行的代码
一般用来取值
作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面
断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
1.语法:
while(条件){
满足条件则执行代码
}
释义:
2.注意事项
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
所以,循环需要具备三要素:
变量起始值
终止条件(没有终止条件,循环会一直执行,造成死循环)
变量变化量(用自增或者自减)
continue和break的区别:
1.for循环语法
for(声明记录循环次数的变量;循环条件;变化值){
循环体
}
循环结束:
for循环里面嵌套for循环
函数:
function,是被设计为执行特定任务的代码块
说明:
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
函数的声明语法:function函数名(){函数体}
函数名命名规范
动词 | 含义 |
---|---|
can | 判断是否可执行某个动作 |
has | 判断是否含义某个值 |
is | 判断是否为某个值 |
get | 获取某个值 |
set | 设置某个值 |
load | 加载某些数据 |
注意:声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数;函数一次声明可以多次调用,每一次函数调用,函数体里面的代码会重新执行一次
函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才
会被执行。函数的功能代码都要写在函数体当中。
声明语法:
调用语法:
●- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
undefined + 任何都是NaN,除了+字符串,这个有隐式转换,会将undefined拼接字符串
undefined || 0 时 ,undefined当false看
当假看,0 undefined null ’‘ false NaN
细节:
断点测试:
F12键控制台,然后到source,点一下断点,如果点第二个按钮或者按F10键不会进入函数内部,直接获取了数据下一句代码;如果按第三个按钮或者按F11键会进入函数内部
9.5.1 作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
全局作用域:
局部作用域
块级作用域
在JavaScript中,根据作用域的不同,变量可以分为
全局变量
局部变量
块级变量
变量有一个特殊情况:
如果函数内部或者块级作用域内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量。
执行20的,执行fn函数时先从自己的作用域开始查找,有就用,没有就到上一级作用域查找,以此类推,找到最后如果没有就是undefined未定义
只要是代码,就至少有一个作用域
写在函数内部的局部作用域
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
作用域链:采取就近原则的方式来查找变量最终的值
函数可分为具名函数和匿名函数
具名函数:
声明:function fn() {}
调用:fn()
匿名函数:
将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
语法:let fn = function(){//函数体}
调用:fn()//函数名()
其中函数的形参和实参使用和具名函数一致
使用场景:后期web API会使用
场景介绍: 避免全局变量之间的污染
语法:注意后面括号的位置
//方式1
(function(){console.log(11)})();
//方式2
(function(){console.log(11)}());
注意:多个立即执行函数要用分号;隔开,要不然会报错
对象是一种数据类型,也是一种无序数据的集合,可以详细地描述某个事物
1.对象声明语法
let 对象名 = {}
2. 对象有属性和方法组成
let 对象名 = {属性名:属性值,方法名:函数}
3. 属性
数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的
4. 属性访问
声明对象,并添加了若干属性后,可以使用 . 或 [] 获得对象中属性对应的值,我称之为属性访问。
简单理解就是获得对象里面的属性值。
声明:let person = {name: ‘Andy’, age: 18}
访问:person.name 或者**[‘name’]**
注意:点后面的属性名一定不要加引号;[] 里面的属性名一定加引号;后期不同使用场景会用到不同的写法
5. 对象中的方法
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
6. 对象中的方法访问
声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,我称之为方法调用
声明:let person = {name: ‘Andy’, age: 18, sayHi: function(){document.write(:hi~~~~)} }
调用:person.sayHi() **后面的括号不可以省略 ** 对象名.方法名()
增删改查操作
查询对象
重新赋值
对象添加新的数据
删除对象中的属性
也就是说,对象如果有这个属性相当于重新赋值,对象如果没有这个属性相当于动态添加一个属性(方法同理)
对象没有像数组一样的length属性,所以无法确定长度
对象里面是无序的键值对, 没有规律. 不像数组里面有规律的下标
使用for in语句
let person = {name: 'ANdy', age: 18}
for(let k in person){
console.log(k);//打印属性名
console.log(person[k]);//打印属性值
}
一般不用这种方式遍历数组、主要是用来遍历对象
理解:k === ‘name’ === ‘age’,所以person.[‘name’] 就是 person.[k]
如果这里是person.k是undefined,因为对象中没有属性k
一定记住: k 是获得对象的属性名, 对象名[k] 是获得 属性值
●- Math对象是JavaScript提供的一个“数学高手”对象
Math.floor(Math.random() * (10 + 1))
Math.floor(Math.random() * (5 + 1)) + 5
Math.floor(Math.random() * (M - N + 1)) + N
可以写在标签内部 比如
想要这样用数据 document.write(
${data[i].src})
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
string ,number,boolean,undefined,null
通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面
num2 = 10 这是因为num2会在内存中开辟一个新的空间(栈中)
正式:简单数据类型存储的值 引用数据类型栈存储的是地址
obj2={age: 20} obj2存的是地址,是obj1的地址,obj1改变了,2也跟着变化