type
status
date
slug
summary
tags
category
icon
学习进度
JavaScript简介
JavaScript是一种运行在客户端(浏览器)的编程语言。
JavaScript的三种书写位置
- 内部(书写的位置尽量写在文档末尾
</body>
前面)
- 外部(外部js标签中间不要写代码,否则会被忽略)
- 行内
JavaScript的两种注释
- 单行注释
//
(ctrl+/)。
- 多行注释
/* */
(shift+Alt+a)。
JavaScript结束符
结束符是:
;
注意:这个结束符是可以省略的,但为了代码统一,结束符要么都写,要么都不写(团队约定)。
JavaScript输入输出语句
输入:
prompt()
输出:
alert()
、document.write()
、console.log()
变量
申明变量关键字:
let
变量赋值运算符:
=
变量拓展let和var的区别
在旧版JavaScript中使用
var
来申明变量而不是let
,let的出现是为了解决var的一些bug问题,所以现在都使用let
来声明变量,了解即可。数组
好处:数组可以保存多个数据。
数组字面量用
[]
中括号表示。常量
概念:使用
const
声明的变量称之为“常量”。使用场景:当某个变量永远不会改变的时候,就可以使用
const
来声明,而不是let
。注意:常量不允许重新赋值,声明的时候必须赋值(初始化)。
数据类型
JS数据类型整体分为两大类:基本数据类型、引用数据类型。
数字类型(Number)
NaN代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。
NaN是粘性的,任何对NAN的操作都会返回NaN。
字符串类型(string)
通过单引号(
’
)、双引号(“
)或反引号(`
)包裹的数据都叫字符串,单引号和双引号没有本质的区别,推荐使用单引号。注意:
- 无论单引号或是双引号必须成对使用。
- 单引号/双引号可以互相嵌套,但是不可以自己嵌套自己(口诀:外双内单,或者外单内双)。
- 必要是可以使用转义符
\
,输出单引号或双引号。
字符串拼接:
场景:
+
运算符可以实现字符串的拼接。口诀:数字相加,字符相连。
模板字符串:可以让我们拼接字符串更简便
模板字符串的用法:用反引号(
``
)包含数据,用${变量名}
来使用变量布尔类型(boolean)
它只有两个固定的值:
true
(真)、false
(假)。未定义类型(undefined)
只声明变量,不赋值的情况下,变量的默认值为
undefined
,一般很少直接为某个变量赋值为undefined
。工作中的使用场景:我们开发中经常声明一个变量,等待传送过来的数据,如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是
undefined
,就可以判断用户是否有数据传递过来。null(空类型)
JS中的
null
仅仅是一个代表“无”、“空”或“值未知”的特殊值。null
开发中的使用场景:把null
作为尚未创建的对象;将来有个变量里面存放的是一个对象,但对象还没创建好,可以先给个null
。null
和undefined
区别:undefined
表示没有赋值
null
表示赋值了,但是内容为空
算术运算符
+
加、-
减、*
乘、 /
除、%
取余。优先级:先乘除取余,后加减,有小括号先算小括号里面的。
取余运算符的使用场景:判断某个数字是否能被整除。
赋值运算符
对变量进行赋值的运算符。
赋值运算符:
=
将等号右边的值赋予给左边,要求左边必须是一个容器。其他的赋值运算符:
+=
、-=
、*=
、/=
、%=
使用这些运算符可以对变量赋值时进行快速操作举例:
num = num + 1
可以简化成num += 1
通过typeof关键字
一元运算符
概念:只需要一个表达式就可以运算的运算符叫一元运算符。
自增:
符号:++
作用:让变量的值+1
自减:
符号:- -
作用:让变量的值-1
使用场景:经常用于计数来使用。比如进行10次操作,用它来计算进行了多少次了。
实际开发:我们一般都是单独使用的,后置++比较多
比较运算符
逻辑运算符
运算符优先级
表达式和语句
表达式:是可以被求值的代码,JavaScript引擎会将其计算出一个结果。
表达式举例:
num=3+4
语句:是一段可以执行的代码
语句举例:
alert()
弹出对话框 console.log()
控制台打印输出程序三大流程控制语句
- 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
- 有时候要根据条件选择执行代码,这种就叫分支结构
- 某段代码被重复执行,就叫循环结构
分支语句包含:if分支语句、三元运算符、switch语句。
if分支语句有三种使用:单分支、双分支、多分支
三元运算符
目标:能利用三元运算符执行满足条件的语句
使用场景:其实是比if双分支更简单的写法,可以使用三元表达式
switch语句
目标:能利用
switch
执行满足条件的语句。释义:找到跟小括号里数据全等的
case
值,并执行里面对应的代码;若没有全等===
的则执行default
里的代码。注意:
switch case
语句一般用于等值判断,不适合于区间判断;switch case
一般需要配合break
关键字使用,没有break
会造成case
穿透。断点调试
作用:学习是可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面:
- 按F12打开开发者工具
- 点到soures一栏
- 选择代码文件
while循环
循环:重复执行一些操作,
while
:在…期间,所以while循环就是在满足条件期间,重复执行某代码。while循环基本语法:
while循环三要素:
- 变量起始值
- 终止条件(没有终止条件,循环会一直执行,造成死循环)
- 变量变化量(用自增或者自减)
- 循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
循环退出
break
:退出循环continue
:结束本次循环,继续下次循环区别:
continue
:退出本次循环,一般用于排除或者跳过某一个选项的时候,可以使用continue
break
:退出整个循环,一般用于结果已经得到,后续的循环不需要的时候可以使用‘无限循环’
while(true)
来构造“无限”循环,需要使用break
退出循环。for(;;)
来构造“无限”循环,同样需要break
退出循环。if多分支语句和switch的区别
for循环
for和while循环的区别
- 当如果明确了循环的次数的时候推荐使用for循环
- 当不明确循环次数的时候推荐使用while循环
for循环嵌套
数组
数组:(Array)是一种可以按顺序保存数据的数据类型(对象数据类型)
术语:
- 元素:数组中保存的每个数据都叫数组元素
- 下标:数组中数据的编号
- 长度:数组中数据的个数,通过数组的
length
属性获得
遍历数组:
目标:能够遍历输出数组里面的元素
- 用循环把数组中每个元素都访问到,一般会用for循环遍历
数组-查看
- 数组名[下标]
数组-改动
- 数组[下标] = 新增
数组-新增
利用push向数组添加元素(数据)
数组.push()
方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度(重点)
语法:
arr.unshift
(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度数组-删除
- 数组名.pop()方法从数组中删除最后一个元素,并返回该元素的值
- 数组名.shift()方法从数组中删除第一个元素,并返回该元素的值
- 语法:
- 例如:
- 数组名.splice()方法 删除指定元素
语法:
start起始位置:指定修改的开始位置(从0计数)
deleteCount:表示要移除的数组元素的个数;可选的,如果省略则默认从指定的起始位置删除到最后
数组排序
数组名.sort()
方法可以排序
- 语法:
函数
css中的抽封
- 函数:
function
,是被设计为执行特定任务的代码块。
- 说明:函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用,提高开发效率。
- 比如:前面使用的
alert()、prompt()、console.log()
都是一些js函数,只不过已经封装好了,我们直接使用的。
函数的声明语法:
函数命名规范:和变量命名基本一致;尽量小驼峰式命名法;前缀应该为动词;命名建议:使用常用动词约定。
- 函数的调用语法:
注意:声明(定义)的函数必须调用才会真正被执行,使用()调用函数;函数不调用自己是不会执行的。
- 函数体:函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码要写在函数体当中。
- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
- 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
理解:形参可以理解为是在这个函数内声明的变量(比如
num1 = 10
)实参可以理解为是给这个变量赋值。注意:开发中尽量保持形参和实参个数一致;多个参数之间用逗号分隔。
- 形参可以看作变量,但是如果一个变量不给值的话那它就是
undefined
,如果undefined
做运算的话结果就会是NaN
。
- 可以改进,先给形参设置好默认值(可以是0),即使用户不传参,也不会跳NaN,这样的程序更加严谨。
函数返回值
为什么要让函数有返回值:函数执行后得到结果,结果是调用者想要拿到的(函数内部不需要输出结果,而是返回结果);对执行结果的扩展性更高,可以让其他的程序使用这个结果。
- 有返回值函数的概念:当调用某个函数,这个函数会返回一个结果出来
- 当函数需要返回数据出去时,用
return
关键字
注意:
- 在函数体中使用
return
关键字能将内部的执行结果交给函数外部使用
return
后面的代码不会再被执行,会立即结束当前函数,使用return
后面的数据不要换行写
return
函数可以没有return
,这种情况函数默认返回值为undefined
- 参数不匹配的情况下:
- 第一种情况实参多于形参的情况下剩余的实参不参与运算
- 第二种情况形参多于实参,
1 + undefined = NaN
作用域
通常来说,一段程序代码中使用到的名字不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
作用:作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
JS中作用域分为两种:
- 全局作用域。函数外部或者整个
script
有效
- 局部作用域。也称为函数作用域,函数内部有效
根据作用域的不同变量也分为两种:
- 全局变量
- 局部变量
作用域的特殊情况:
如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐。
变量的访问原则:
- 只要是代码,就至少有一个作用域
- 写在函数内部的是局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 访问原则:在能够访问到的情况下 先局部,局部没有载找全局
- 作用域链:采取就近原则的方式来查找变量最终的值
匿名函数:
- 函数可以分为两种:具名函数(有名字)、匿名函数(没名字)。
- 没有名字的函数,无法直接使用。
- 函数表达式:将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们把它称为函数表达式
语法:
调用:(其中函数的形参和实参使用跟具名字一致)
立即执行函数:
作用:防止变量污染
注意事项 :无需调用,立即执行,其实本质已经调用了;多个立即执行函数之间用分号隔开。
逻辑运算符里的短路
- 短路:只存在
&&
和||
中,当满足一点条件会让右边代码不执行。
- 原因:通过左边能得到整个式子的结果,因此没有必要在判断右边。
- 运算结果:无论
&&
还是||
,运算结果都是最后被执行的表达式值,一般用在变量赋值
转换为Boolean型
显示转换:
举例:
console.log(undefined && 20)
这里的与不会返回布尔型,它会把undefined
当做假来看。console.log(10 || 20)
这里的或遇到两个都是真,则返回第一个。隐性转换:
对象
- 对象(object):JavaScript里的一种数据类型。
- 可以理解为是一种无序的数据集合,注意数组是有序的数据集合
- 用来描述某个事物,例如描述一个人
- 人有姓名、年龄、性别等信息、还有吃饭睡觉爱好等功能
- 如果用多个变量保存则比较散,用对象比较统一
- 比如描述班主任信息:
- 静态特征(姓名,年龄,身高,性别,爱好)→可以使用数字,字符串,数字,布尔类型等表示。
- 动态行为(点名,唱,跳,rap)→使用函数表示。
- 对象声明语法
- 实际开发中,我们多用花括号。
{}
是对象字面量
- 对象由属性和方法(其本质是函数)组成
- 手机举例
- 属性:信息或叫特征(名词)。比如手机尺寸、颜色、重量等…
- 方法:功能或叫行为(动词)。比如手机打电话、发短信、玩游戏…
注意:
- 属性都是成对出现的, 包括属性名和值,它们之间使用英文
:
分隔。
- 多个属性之间使用英文
,
分隔。
- 属性就是依附在对象上的变量(外面是变量,对象是属性)。
- 属性名可以使用
“”
或“
,一般情况下省略,除非名称遇到特殊符号如空格、中横线等。
null
是个空对象,通常只用它来表示不存在的对象。
对象-查
- 声明对象,并添加了若干属性后,可以使用.获取对象中属性对应的值
.
我称之为属性访问。
- 语法:
对象名.属性名
- 简单理解就是获得对象里面的属性值
对象-查(另一种写法)
- 语法:
对象名['属性名']
- 对于多词属性或者
-
等属性,用第一种方法的.
点就不能用了。
- 可以采取对象[’属性‘]方式,单引号和双引号都可以(必须写引号)。
对象-改
- 语法:
对象名.属性=新值
对象-增
- 语法:
对象名.新属性=新值
- 技巧:新增-大括号里面用冒号,大括号外面用等号。
- 语法和改一样,主要看属性名,存在的话就是改,不存在属性名就增。
对象-删(了解)
- 语法:
delete 对象名.属性
对象中的方法
- 数据行为性的信息称为方法,比如跑步、唱歌,一般是动词性的,其本质是函数。
- 方法是由方法名和函数两部分构成,它们之间使用
:
分隔 - 多个属性之间使用英文
,
分隔 - 方法是依附在对象中的函数
- 方法名可以使用“”或’‘,一般情况下省略,除非名称遇到特殊符号如空格、中横线等。
- 声明对象并添加了若干方法后,可以使用
.
调用对象中的函数,称之为方法调用。
- 也可以添加形参和实参。
- 注意:千万别忘了给方法名后面加小括号。
对象遍历
- 目的:能够遍历输出对象里面的元素。
- 注意:对象里面是无序的键值对没有规律,不像数组里面有规律的下标;对象也没有像数组一样的
length
属性,所以无法确认长度。
- 一般不用这种方式遍历数组,主要是用来遍历对象。
fon in
语法中的k是一个变量,在循环的过程中依次代表对象的属性名。
- 由于
k
是变量,所以必须使用[]
语法解析。
- 一定记住:
k
是获取对象的属性名(字符串类型),对象名[k]
是获得属性值。
内置对象
- JavaScript内部提供的对象,包含各种属性和方法给开发者调用。
内置对象-Math
- 介绍:Math对象是JavaScript提供的一个“数学”对象。
- 作用:提供了一系列做数学运算的方法。
- Math对象包含的方法有:
random
:生成0-1之间的随机数(包含0不包括1)ceil
:向上取整floor
:向下取整max
: 找最大数min
: 找最小数pow
:幂运算abs
:绝对值
内置对象-生成任意范围随机数
拓展-术语解释
基本数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。
- string,number,boolean,undefined,null
- 引用类型:复杂类型数据,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。
- 通过new关键字创建对象(系统对象,自定义对象),如Object、Array、Date等
堆栈空间分配区别:
- 栈(操作系统):由操作系统自动分配释放参数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。(简单数据类型存放到栈里面)
- 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。(引用数据类型存放到堆里面)
变量声明
- 变量声明有三个
var
、let
和const
。
- 首先排除
var
,因为快被淘汰。
- 建议:
const
优先,尽量使用const
。 const
语义化更好- 很多变量我们声明的时候就知道它不会被更改的,所以使用
const
更好 - 实际开发中也是,比如react框架,基本
const
- 有了变量先给
const
,如果发现它后面是要被修改的,再改为let
- 其实很多一开始声明的时候就知道它会不会变 。
const
声明的值不能更改,而且const
声明变量的时候需要里面进行初始化。- 但是对于引用数据类型,
const
声明的变量,里面存的不是值,是地址。 - 只要是加了中括号大括号都会改变原有的地址,这是错误的,它们的地址不一样。
- 建议数组和变量使用
const
来声明。 - 如果基本数据类型的值或者引用类型的地址发生变化的时候,需要用
let
(比如for
循环中的i++
)。
Web API基本认知
作用和分类
作用:就是使用JS去操作html和浏览器。
分类:DOM(文档对象模型)、BOM(浏览器对象模型)。
DOM(文档对象模型)
- DOM(文档对象模型)是用来呈现以及与任意HTML或XML文档交互的API。
- 白话文:DOM是浏览器提供的一套专门用来操作网页内容的功能。
- DOM作用:开发网页内容特效和实现用户交互。
- DOM树:将HTML文档以树状结构直观的表现出来,我们称之为文档或DOM数。
- 描述网页内容关系的名词
- 作用:文档树直观的体现了标签与标签之间的关系
DOM对象(重要)
- DOM对象:浏览器根据html标签生成的JS对象
- 使用的标签属性都可以在这个对象上面找到。
- 修改这个对象的属性会自动映射到标签身上。
- DOM的核心思想:把网页内容当对象来处理。
获取DOM对象
- 选择匹配的第一个元素。
- 参数:包含一个或多个有效的CSS选择器字符串。
- 返回值:CSS选择器匹配的第一个元素,一个HTMLElement对象。(没有匹配到则返回null)
- 选择匹配的多个元素
- 参数:包含一个或多个有效CSS选择器字符串
- 返回值:CSS选择器匹配NodeList对象集合(数组)
伪数组
其他获取DOM元素方法(了解)
操作元素内容
- 作用:能够修改元素的文本更换内容。
- DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象。
- 就是操作对象使用的点语法。
- 想要修改标签元素的里面内容,则可以使用如下几种方式:
对象.innerText属性
对象.innerHTML属性
元素.innerText属性
- 将文本内容添加、更新到任意标签位置。
- 显示纯文本,不解析标签。
元素.innerHTML属性
- 将文本内容添加/更新到任意标签位置。
- 会解析标签,多标签建议使用模板字符。
通过DOM修改元素属性
语法:
对象.元素属性 = '值'
通过style更改样式属性
语法:
对象.style.样式属性 = '值'
- 样式属性是多单词组成使用小驼峰命名法
操作类名(className)操作CSS
- 如果修改样式比较多,直接通过style属性修改比较繁琐,可以通过借助于CSS类名的形式。
- 语法:
- 注意:
- 由于class是关键字,所以使用className去代替。
- className是使用新值换旧值,如果需要添加一个类,需要保留之前的类名。
- 理解:
- 频繁使用style属性修改很麻烦,就把要修改的内容一起写在style里面的一个类里,第一步获取元素,然后把写好的类样式引用给元素即可,元素就可以实现类里面的样式。
通过classList操作类控制CSS
- 为了解决className容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
- 语法
操作表单元素属性
- 表单很多情况也需要修改属性,比如点击眼睛,观看和隐藏密码。
- 正常的有属性有取值 跟其他标签属性没有任何区别
语法:
- 表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示,如果
true
代表添加了该属性,如果是false
代表移除了该属性。比如:disabled
、checked
、selected
自定义属性
- 标准属性:标签天生自带的属性,比如class id title等,可以直接使用点语法操作比如:
disabled
、checked
、selected
。
- 自定义属性:
- 在html5中推出来了专门的
data-
自定义属性。 - 在标签上一律以
data-
开头。 - 在DOM对象上一律以
dataset
对象方式获取。
定时器-间歇函数
- 网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发。
- 例如:网页中的倒计时。要实现这种需求需要定时器函数。
- 定时器有两种,先说间歇函数。
- 能够使用定时器函数重复执行代码。
- 定时器函数可以开启和关闭定时器
- 开启定时器
- 作用:每隔一段时间调用这个函数。
- 间隔时间单位是毫秒。
- 关闭定时器
一般不会刚创建就停止,而是满足某些一定条件再停止。
事件监听
- 事件:事件是编程时系统内发生的动作或者发生的事情,比如:用户在网页上单击一个按钮。
- 事件监听:就是让程序检测是否有事件产生,一旦有时间触发,就立即调用一个函数做出响应,也称之为绑定事件或者注册事件,比如:鼠标经过显示下拉菜单,比如点击可以播放轮播图等等。
- 语法:
- 事件监听三要素:
- 事件源:哪个dom元素被事件触发了,要获取dom元素。
- 事件类型:用什么方式触发,比如鼠标单击
click
、鼠标经过mouseover
等。 - 事件调用的函数:要做什么事情。
监听事件版本
事件类型
事件对象
概述:事件对象也是个对象,这个对象里有事件触发时相关的信息(例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息)。
- 使用场景:可以判断用户按下哪个键、可以判断鼠标点击了哪个元素,从而做相应的操作。
- 语法:如何获取
- 在事件绑定的回调函数的第一个参数就是事件对象。
- 一般命名为
event
、ev
、e
- 常见事件对象属性
环境对象
环境对象:指的是函数内部特殊的变量
this
,它代表着当前函数运行时所处的环境。- 函数调用方式不同,this指的对象也不同。
- “谁调用,this就是谁”是判断this指向的粗略规则。
回调函数
- 如果将函数A作为参数传递给函数B时,我们称函数A为回调函数。
- 回调函数本质还是函数,只不过把它当成参数使用。
- 使用匿名函数作为回调函数比较常见。
事件捕获
- 事件流指的是事件完整执行过程中的流动路径。
- 捕获阶段是从父到子,冒泡阶段是从子到父。(实际工作都是使用事件冒泡为主)
- 事件捕获概念:从DOM的根元素开始去执行对应的事件(从外到里)
- 事件捕获需要写对应代码才能看到效果
- 说明:
addEventListener
第三个参数传入true
代表是捕获阶段触发(很少使用)。- 若传入
false
代表冒泡阶段触发,默认就是。 - 若是L0事件监听,则只有冒泡阶段,没有捕获。
事件冒泡
- 概念:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡。
- 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件。
- 事件冒泡是默认存在的。
- L2事件监听第三个参数是
false
,或者默认都是冒泡。
阻止冒泡
问题:因为默认就有冒泡模式的存在,所有容易导致事件影响到父级元素。
需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡。
前提:阻止事件冒泡需要拿到事件对象。
语法:
注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效。
解绑事件
on事件方式,直接使用null覆盖偶就可以实现事件解绑
语法:
事件委托
- 事件委托是利用事件流的特征解决一些开发需求的知识技巧。
- 优点:减少注册次数,可以提高程序性能。
- 原理:事件委托其实就是利用事件冒泡的特点。给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。
- 实现:对象事件.target.tagName可以获得真正触发事件的元素。
阻止元素默认行为
e.preventDefault()
页面加载事件
- 加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件。
- 事件名:load
- 监听页面所有资源加载完毕:给window添加load事件。
页面滚动事件
- 滚动条在滚动的时候持续触发的事件。
- 事件名:scroll
- 监听整个页面滚动:
- 获取位置(
scrollLeft
和scrollTop
属性) - 获取被卷进去的大小。
- 获取元素内容往左、往上滚出去看不到的距离。
- 这两个值是可读写的(可以赋值)。
- 开发中,经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素。
- 固定坐标分别有这两种写法。
- 两种获取元素尺寸的方法
- 获取元素的可见部分宽高(不包含边框,
margin
,滚动条等)。 clientWidth
和clientHeight
是读写属性- 获取元素的自身宽高,包含元素自身设置的宽高、padding、border。
- 获取出来的是数值,方便计算。
- 获取的是可视宽高,如果盒子是隐藏的,获取的结果是0。
- 获取元素距离自己定位父级元素的左、上距离。
offsetLeft
和offsetTop
是只读属性。- 获取位置:
元素尺寸于位置-尺寸
element.getBoundingClientRect()
该方法返回元素的大小及其相对于视口的位置。总结
实例化
new Date()
日期对象方法
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式。
时间戳
- 使用场景:如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成。
- 时间戳:是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式。
- 算法:将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数;剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间。
- 重点记住:
+new Date()
因为可以返回当前时间或者指定的时间戳。
DOM节点
- DOM节点:DOM树里面每个内容都称之为节点。
- 节点的类型
- 元素节点
- 所有的标签 比如
body
、div
html
是根节点- 属性节点
- 所有的属性 比如
class
- 文本节点
- 所有的文本
- 其他
查找节点
- 节点关系:针对的找亲戚返回的都是对象
- 父节点
- 子节点
- 兄弟节点
- 父节点查找:
parentNode
属性。- 返回最近一级的父节点,找不到返回为null。
- 子节点查找:
childNodes
- 获得所有子节点、包括文本节点(空行、换行)、注释节点等。
children
属性(重点)- 仅获得所有元素节点,返回的还是一个伪数组。
- 兄弟关系查找:
- 下一个兄弟节点:
nextElementSibling
属性。 - 上一个兄弟节点:
previousElementSibling
属性。
增加节点
- 很多情况下,我们需要在页面中增加元素
- 比如,点击发布按钮,可以新增一条信息。
- 一般情况下,我们新增节点,按照如下操作:
- 创建一个新的节点。
- 把创建的新的节点放入到指定元素内部。
- 创建节点
- 既创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点。
- 创建元素节点方法:
- 增加节点
- 特殊情况下,我们新增节点,按照如下操作:
- 复制一个原有的节点
- 把复制的节点放入到指定的元素内部
- 克隆节点
cloneNode
会克隆出一个跟原标签一样的元素,括号内传入布尔值。- 若为true,则代表克隆时会包含后代节点一起克隆。
- 若为false,则代表克隆时不包含后代节点。
- 追加节点
- 创建之后要想在界面看到,还得插入到某个父元素中。
- 插入到父元素的最后一个子元素
- 插入到父元素中某个子元素的前面
- 删除节点
- 若一个节点在页面中已不需要时,可以删除它。
- 在JavaScript原生DOM操作中,要删除元素必须通过父元素删除。
- 如果不存在父子关系则删除不成功。
- 删除节点和隐藏节点(
display:none
)有区别的:隐藏节点还是存在的,但是删除,则从html中删除节点。
M端事件
插件
BOM(浏览器对象模型)
- BOM,浏览器对象模型(Browser Object Model),它定义了与浏览器进行交互的方法和接口,由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。
- window对象是一个全局对象,也可以说是JavaScript中的顶级对象。
- 像
document
、alert()
、console.log()
这些都是window的属性,基本BOM的属性和方法都是window的。
- 所有通过
var
定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
- window对象下的属性和方法调用的时候可以省略window。
定时器-延时函数
- JavaScript内置的一个用来让代码延迟执行的函数,叫
setTimeout
。
- 语法:
- setTimeout仅仅只执行一次,所以可以理解为就是把一段代码延迟执行。
- 清除延时函数:
- 注意:
- 延时器需要等待,所以后面的代码先执行。
- 每一次调用延时器都会产生一个新的延时器。
- 两种定时器对比:执行次数
- 延时函数:执行一次。
- 间歇函数:每隔一段时间就执行一次,除非手动清除。
JS执行机制
同步和异步本质区别:这条流水线上各个流程的执行顺序不同。
- 由于主线程不断的重复获取任务、执行任务、再获取任务、再执行,所以这种机制被称之为事件循环(event loop)。
location对象
location
的数据类型是对象,它拆分并保存了URL地址的各个组成部分。
- 常用的属性和方法:
search
属性获取地址中携带的参数,符号?后面部分、reload
方法是用来刷新当前页面的,传入参数true
表示强制刷新。hash
属性获取地址中的哈希值,符号#后面部分
navigator对象
navigator
的数据类型是对象,该对象下记录了浏览器自身的相关信息。
- 常用属性和方法:通过userAgent检测浏览器的版本及平台。
histroy对象
- history的数据类型是对象,主要管理历史记录,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等。
- 常用属性和方法:
history
对象一般在实际开发中比较少用,但是会在一些OA办公系统中见到。
本地存储介绍
本地存储分类-localStorage
- 作用:可以将数据永久存储在本地(用户的电脑),除非手动删除,否则关闭页面也会存在。
- 特性:
- 可以多窗口(页面)共享(同一浏览器可以共享)。
- 以键值对的形式存储使用。
- 本地存储只能存储字符串数据类型,无法存储复杂的数据类型。
- 语法:
- 存储数据:
localStorage.setltem(key,value)
- 获取数据:
localStorage.getltem(key)
- 删除数据:
localStorage.removeltem(key)
本地存储分类-sessionStorage
- 特性:
- 生命周期为关闭浏览器窗口。
- 在同一个窗口(页面)下数据可以共享。
- 以键值对的形式存储使用。
- 用法跟localStorage基本相同。
存储复杂数据类型
- 要先将复杂数据(对象类型)转换成JSON字符串存储本地存储中。
- 语法:
JSON.stringify
- 取出来的时候把字符串再次转换为对象即可还原。
- 语法:
JSON.parse
数组中map方法(迭代数组)
map
可以遍历数组处理数据,并且返回新的数组。
map
也称为映射。映射是个术语,指两个元素的集之间元素互相“对应”的关系。map
重点在于有返回值,forEach
没有返回值。
数组中join方法
- 作用:
join()
方法用于把数组中的所有元素转换成一个字符串
- 语法:
- 参数:数组元素是通过参数里面指定的分隔符就行分隔的,空字符串(
’’
),则使用元素之间都没有任何字符;任何不传参默认是逗号分割。
正则表达式
- 正则表达式(Regular Expression)是用于匹配字符串中文符组合的模式,在JS中,正则表达式 也是对象。
- 通常用来查找、替换那些符号正则表达式的文本,许多语言都支持正则表达式。
- 正则表达式在JS中的使用场景:
- 例如验证表单:用户名表单只能输入英文字母、数字或者下划线,昵称输入框中可以输入中文(匹配)。
- 过滤掉页面内容中的一些敏感词(替换), 或从字符串中获取我们想要的特点部分(提取)等。
test()方法
- 语法:
test()
方法,用来查看正则表达式与指定的字符串是否匹配。
exec()方法
- 语法:
exec()
方法, 在一个指定字符串中执行一个搜索匹配。
元字符
- 是一些具有特殊含义的字符,可以极大提供了灵活性和强大的匹配功能。
- 比如英文26个英文字母,我们使用元字符[a-z]简介和灵活。
- 对元字符进行分类:
- 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
- 注意:如果
^
和$
在一起,表示必须是精确匹配。 - 词量(表示重复次数)
- 量词用来设定某个模式出现的次数
边界符 | 说明 |
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁开始) |
量词 | 说明 |
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
- 字符类
[]
匹配字符集合。[a-z]
表示a-z26个英文字母都可以。[a-zA-Z]
表示大小写都可以。[0-9]
表示0~9的数字都可以。[^a-z]
匹配除了小写字母以外的字符。(注意写在中括号里面).
匹配除换行符之外的任何单个字符。- 预定义:指的是某些常见模式的简写方式。
预定类 | 说明 |
\d | 匹配0-9之间的任一数字,相当于 [0-9] |
\D | 匹配所有0-9以外的字符,相当于 [^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于 [A-Za-z0-9_] |
\W | 除所有字母、数字和下划线以外的字符,相当于 [^A-Za-z0-9_] |
\s | 匹配空格(包括换行符、制表符、空格符等),相等于 [\t\r\n\v\f] |
\S | 匹配非空格的字符,相当于 [^\t\r\n\v\f] |
- 修饰符:修饰符约束正则执行的某些细节行为,如是区分大小写、是否支持多行匹配等。
- i是单词
ignore
的缩写,正则匹配时字母不区分大小写。 - g是单词
global
的缩写,匹配所有满足正则表达式的结果。
作用域
- 作用域规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问。
- 作用域分为全局作用域和局部作用域。
- 局部作用域又分为函数作用域和块级作用域。
- 函数作用域:
- 函数内部就称之为函数作用域。
- 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
- 函数的参数也是函数内部的局部变量。
- 不同函数内部声明的变量无法互相访问。
- 函数执行完毕后,函数内部的变量实际被清空了(回收)。
- 块级作用域:
- 在
{}
大括号内就称之为块级作用域 let
声明的变量会产生块作用域,var
不会产生块作用域。const
声明的常量也会产生块作用域。- 不同代码块之间的变量无法互相访问。
- 推荐使用
let
或const
。
- 全局作用域:
- 在
<script>
标签和.js
文件的最外层就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。 - 全局作用域中声明的变量,任何其他作用域都可以被访问。
- 函数中未使用任何关键字声明的变量为全局变量。
- 为window对象动态添加的属性默认也是全局的。
- 不推荐使用全局作用域,尽可能少的声明全局变量,防止全局变量被污染。
- 作用域链:
- 作用域链本质上是底层的变量查找机制。
- 在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域。
- 嵌套关系的作用域串联起来形成了作用域链。
- 相同作用域中按着从小到大的规则查找变量。
- 子作用域能够访问父作用域,父级作用域无法访问子级作用域。
垃圾回收机制
垃圾回收机制(Garbage Collection)简称GC。
- JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。
- js环境中分配的内存,一般有如下生命周期:
- 内存分配:当我们声明变量、函数、对象的时候,系统会自动为它们分配内存。
- 内存使用:即读写内存,也就是使用变量、函数等。
- 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存。
- 全局变量一般不会回收(关闭页面才回收)。
- 一般情况下局部变量的值,不用了会被自动回收掉。
内存泄漏:程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏。
堆栈空间分配区别:
栈(操作系统):由操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放到栈里面。
堆(操作系统):一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂的数据类型放到堆里面。
两种常见的浏览器垃圾回收算法:引用计数法和标记清除法。
闭包
- 概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域。
- 理解:内层函数 + 外层函数的变量
- 闭包作用:封闭数据,提供操作,外部也可以访问函数内部的变量。闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。
- 闭包应用:实现数据的私有。
变量提升
- 变量提升是JS中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在与
var
声明变量)。
- 变量在未声明即被访问时会报语法错误。
- 变量在
var
声明之前即被访问,变量的值为undefined
。
let
和const
声明的变量不存在变量提升。
- 变量提升出现在相同作用域当中。
- 实际开发中推荐先声明再访问变量。
函数提升
- 函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
- 函数提升能够使函数的声明调用更灵活。
- 函数表达式不存在提升的现象。
- 函数提升出现在相同作用域当中。
动态参数
- arguments是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。
- arguments是一个伪数组,只存在于函数中。
- arguments的作用是动态获取函数的实参。
- 可以通过for循环依次得到传递过来的实参。
剩余函数
- 剩余参数允许我们将一个不确定数量的参数表示为一个数组。
- 语法:
…自定义数组名
…
是语法符号,置于最末函数形参之前,用户获取多余的实参。
- 借助
…
获取的剩余实参,是一个真数组。
- 开发中,还是多提倡使用剩余参数。
- 下面案例中,形参
a
得到1,形参b
得到2,形参arr
数组得到3。
展开运算符
- 展开运算符(Spread Operator)允许你在调用函数或创建数组时,将一个可迭代的元素序列(如数组)展开,作为函数的参数或数组的元素。
- 作用:可以把数组展开,可以利用求数组最大值以及合并数组等操作。
- 下面的例子中,数组是没有方法直接取最大最小值,这时就需要把数组展开就可以使用对应的方法了。还可以做数组之间的合并拼接。
- 展开运算符和剩余参数的区别(语法很相似):
- 剩余参数:函数参数使用,得到真数组。
- 展开运算符:数组中使用,数组展开。
箭头函数
- 箭头函数属于表达式函数,因此不存在函数提升。
- 箭头函数只有一个参数时可以省略
()
小括号
- 箭头函数函数体只有一行代码时可以省略
{}
大括号,并自动作为return
返回值被返回。
- 箭头函数中只有一个表达式时不可以加花括号。
- 加括号的函数体返回对象字面量表达式。
- 箭头函数没有arguments动态参数,但是有剩余参数。
- 箭头函数不会创建自己的this,他只会从自己的作用域链的上一层沿用this。
- 在开发中使用箭头函数前需要考虑函数中this的值,事件回调函数使用箭头函数时,this为全局的window,因此DOM事件回调函数为了简便,还是不太推荐使用箭头函数。
解构赋值
解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值。
数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法。
解构赋值分为:数组解构和对象解构。
数组解构
- 将数组的元素分配给单独的变量
- 数组解构的基本语法
- 交互两个变量的值
- 特殊情况、设置默认值
对象解构
对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法。
- 对象解构的语法:
对象解构案例:
遍历数组forEach方法(重点)
forEach()
方法用于调用数组的每个元素,并将元素传递给回调函数。
- 语法:
- 注意:
forEach
主要是遍历数组,没有返回值,适合于遍历数组对象。- 参数当前数组元素必须要写的,索引号可选。
筛选数组filter方法(重点)
filter()
方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
- 主要使用场景:筛选数组符合条件的元素,并返回筛选之后元素的新数组。
- 返回值:返回数组,包含了符合条件的所有元素,如果没有符合的元素则返回空数组。
- 参数:
currentValue
(item
)必须写,index
可选。
- 因为返回新数组,所以不会影响原数组。
- 语法:
创建对象的三种方式
构造函数
- 构造函数是一种特殊的函数,主要用来初始化对象。
- 构造函数在技术上是常规函数。
- 构造函数的两个约定:
- 它们的命名以大写字母开头。
- 它们只能“new”操作符来执行。
- 使用
new
关键字调用函数的行为被称为实例化。
- 实例化构造函数时没有参数时可以省略
()
。
- 构造函数内部无需写
retrun
,返回值即为新建的对象。
- 构造函数内部的
return
返回的值无效,所以不要写retrun
。
new Oject()
new Date()
也是实例化构造函数
实例成员&静态成员
实例成员:通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员(实例成员包括实例属性和实例方法)。
静态成员:构造函数的属性和方法被称为静态成员(静态属性和静态方法)。
注意:
- 静态成员只能构造函数来访问。
- 静态方法中的this指向构造函数。
内置构造函数
- 在JS中最主要的数据类型有6种:
- 基本数据类型:字符串、数值、布尔、undefined、null
- 引用类型:对象
但我们会发现一个特殊情况,如下图
- 其实字符串、数值、布尔、等基本类型也都有专门的构造函数,这些称为包装类型。
- JS中几乎所有的数据都可以基于构造函数创建。
内置构造函数
引用类型:
Object
,Array
,RegExp
,Date
等。包装类型:
String
,Number
,Boolean
等。三个常用静态方法
Object.keys
静态方法获取对象中所有属性名(键)
Oject.values
静态方法获取对象中所有的属性值 (值)
Object.assign
静态方法常用于对象拷贝,和追加。
数组常见实例方法 - 核心方法
方法 | 作用 | 说明 |
forEach | 遍历数组 | 不返回数组,经常用于查找遍历数组元素 |
filter | 过滤数组 | 返回新数组,返回的是筛选满足条件的数组元素 |
map | 迭代数组 | 返回新数组,返回的是处理之后的数组元素,想要使用返回的新数组 |
reduce | 累计器 | 返回累计处理的结果,经常用于求和等 |
图画便于记忆:
数组常见方法 - 其他方法
实例方法 | 说明 |
join | 数组元素拼接为字符串,返回字符串(重点) |
find | 查找元素,返回符合测试条件的第一个数组元素值,如果没有符合条件则返回undefined(重点) |
every | 检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回true,否则返回false(重点) |
some | 检测数组中的元素是否满足指定条件,如果数组中元素满足条件返回true,否则返回false |
concat | 合并两个数组,返回生成的新数组 |
sort | 对原数组单元值排序 |
splice | 删除或替换原数组单元 |
reverse | 反转数组 |
findIndex | 查找元素的索引值 |
图画便于记忆:
字符串常见方法
实例方法 | 说明 |
length | 用来获取字符串的长度(重点) |
split('分隔符') | 用来将字符串拆分成数组(重点) |
substring(需要截取第一个字符索引号[,结束索引号]) | 用于字符串截取(重点) |
startsWith(检测字符串[,检测位置索引号]) | 检测是否以某字符开头(重点) |
includes(搜索的字符串[,检测位置索引号]) | 判断一个字符串是否包含在另一个字符串中,根据情况返回true或false(重点) |
toUpperCase | 用于将字母转换成大写 |
toLowerCase | 用于将字母转换成小写 |
indexOf | 检测是否包含某字符 |
endsWith | 检测是否以某字符结尾 |
replace | 用于替换字符串,支持正则匹配 |
match | 用于查找zfc,支持正则匹配 |
数值型常见方法
toFixed(保留几位小数)
设置保留小数的位数编程思想
编程思想主要包括两种:面向过程和面向对象。
- 面向过程:面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。
- 面向对象:面向对象是把事务分解成为一个个对象,然后由对象之间分工合作。
- 在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工。
- 面向对象编程具有灵活、代码可复用,容易维护和开发的优点,更适合多人合作的大型软件项目。
- 面向对象的特性:封装性、继承性、多态性。
面向过程编程
- 优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用的面向过程编程。
- 缺点:没有面向对象易维护、易复用、易扩展。
面向对象编程
- 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护。
- 缺点:性能比面向过程低。
构造函数实现封装以及存在的问题
构造函数:
- 封装是面向对象思想中比较重要的一部分,JS面向对象可以通过构造函数实现的封装。
- 同样的将变量和函数组合到了一起并能通过this实现数据的共享,所不同的是借助构造函数创建出来的实例对象之间是彼此不影响的。
总结:
- 构造函数体现了面向对象的封装特性。
- 构造函数实例创建的对象彼此独立,互不影响。
构造函数同时也会存在一些问题,看下面的例子:
像
uname
、age
这种简单数据类型它存的是值,是放在栈里面的,不需要就可以回收了,但是sing
存的是一个引用的复杂数据类型,每创建一个对象都会在堆里面开创相对应的空间来存放复杂数据类型,这样的看的话它们虽然存的是同一个函数,但地址指向的存储位置是完全不同的,所以就会返回false
(同一个存储位置才会返回true
)。虽然是同一个函数但要开创不同的空间来存储,这个时候构造函数就存在浪费内存的问题(需要通过原型来解决)。
原型
- 构造函数通过原型分配的函数是所有对象所共享的。
- JS规定,每一个构造函数都有一个
prototype
属性,指向另一个对象,所以我们也称为原型对象。
- 这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存。
- 我们可以把那些不会的方法,直接定义在
prototy
对象上,这样所有对象的实例就可以共享这些方法。
- 构造函数和原型对象中的
this
都指向实例化的对象。
constructor属性
- 每个原型对象里面都有个constructor属性(constructor构造函数)。
- 该属性指向该原型对象的构造函数(理解:指向我爸爸,我是一个有爸爸的儿子)
使用场景:如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象constructor就不再指向当前构造函数了,此时我们就需要在修改过后的原型对象中添加一个constructor指向原来的构造函数。
对象原型
对象都会有一个属性
__proto__
指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype
原型对象的属性和方法,就是因为对象有__proto__
原型的存在。对象原型需要注意:
__proto__
是JS非标准属性。
[[prototype]]
和__proto__
意义相同(不同的浏览器显示有差异)。
__proto__
是个只读属性,只能获取不能赋值。
__proto__
用来表明当前实例对象指向哪个原型对象prototype
。
- 对象原型(
__proto__
)指向原型对象prototype
。
__proto__
对象原型和prototpye
原型对象里面都有一个constructor
属性,指向创建该实例对象的构造函数。
原型继承
- 继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JS中大多是借助原型对象实现继承的特性。
- 所有的对象都是通过对象字面量创建的,而对象字面量实际上是一个函数,它的原型属性是一个对象,这个对象定义了这个对象字面量的所有属性和方法。因此,当我们创建一个对象字面量时,它的原型就是它的构造函数的原型,也就是它的构造函数本身。因此,如果我们想要让一个对象能够继承另一个对象的属性和方法,我们只需要将它的原型设置为另一个对象的构造函数即可。
因为:男人和女人都同时使用了一个对象,根据引用类型的特点,他们指向同一个对象,修改其中一个都会有影响。
原型链
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链。
- 每个对象都有一个原型对象,这个原型对象定义了这个对象的属性和方法。而这个原型对象就是该对象的原型链的一部分。当我们在一个对象上查找一个属性,如果这个对象本身没有这个属性,JavaScript就会在该对象的原型(也就是它的
[[Prototype]]
属性)上查找,如果还没有,就会继续查找原型的原型,一直找到找到顶层的原型对象或者找到属性为止,通过这种方式,不同的对象可以共享它们的原型对象的属性和方法,从而避免了每个对象都复制一份相同的代码,提高了代码的效率和复用性。
- 只要是对象(实例对象,原型对象)都有
__proto__
。
- 只要原型对象就有
constructor
,指回创建该原型对象的构造函数。
- 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
- 如果没有就查找它的原型(也就是
__proto__
指向的prototype
原型对象)。
- 如果还没有就查找原型对象的原型(
Object
的原型对象)
- 以此类推一直找到
Object
为止(null
)
__proto__
对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。
- 可以使用
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。
使用面向对象思想,模态框案例
- 作者:heliang
- 链接:https://heliang.fun/article/JavaScript-note
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。