, 或
元素上:
< a href = " #" class = " btn btn-info" role = " button" > 链接按钮a >
< button type = " button" class = " btn btn-info" > 按钮button >
< input type = " button" class = " btn btn-info" value = " 输入框按钮" >
< input type = " submit" class = " btn btn-info" value = " 提交按钮" >
按钮设置边框
< button type = " button" class = " btn btn-outline-primary" > 主要按钮button >
< button type = " button" class = " btn btn-outline-secondary" > 次要按钮button >
< button type = " button" class = " btn btn-outline-success" > 成功button >
< button type = " button" class = " btn btn-outline-info" > 信息button >
< button type = " button" class = " btn btn-outline-warning" > 警告button >
< button type = " button" class = " btn btn-outline-danger" > 危险button >
< button type = " button" class = " btn btn-outline-dark" > 黑色button >
< button type = " button" class = " btn btn-outline-light text-dark" > 浅色button >
不同大小的按钮
< button type = " button" class = " btn btn-primary btn-lg" > 大号按钮button >
< button type = " button" class = " btn btn-primary" > 默认按钮button >
< button type = " button" class = " btn btn-primary btn-sm" > 小号按钮button >
块级按钮
通过添加 .btn-block 类可以设置块级按钮:
< button type = " button" class = " btn btn-primary btn-block" > 按钮 1button >
激活和禁用的按钮
按钮可设置为激活或者禁止点击的状态。
.active 类可以设置按钮是可用的, disabled 属性可以设置按钮是不可点击的。 注意 元素不支持 disabled 属性,你可以通过添加 .disabled 类来禁止链接的点击。
< button type = " button" class = " btn btn-primary active" > 点击后的按钮button >
< button type = " button" class = " btn btn-primary" disabled > 禁止点击的按钮button >
< a href = " #" class = " btn btn-primary disabled" > 禁止点击的链接a >
颜色
代表指定意义的文本颜色
柔和的文本。
重要的文本。
执行成功的文本。
代表一些提示信息的文本。
警告文本。
危险操作文本。
副标题。
深灰色文字。
浅灰色文本(白色背景上看不清楚)。
白色文本(白色背景上看不清楚)。
在链接中使用
背景颜色
< div class = " container" >
< h2> 背景颜色h2 >
< p class = " bg-primary text-white" > 重要的背景颜色。p >
< p class = " bg-success text-white" > 执行成功背景颜色。p >
< p class = " bg-info text-white" > 信息提示背景颜色。p >
< p class = " bg-warning text-white" > 警告背景颜色p >
< p class = " bg-danger text-white" > 危险背景颜色。p >
< p class = " bg-secondary text-white" > 副标题背景颜色。p >
< p class = " bg-dark text-white" > 深灰背景颜色。p >
< p class = " bg-light text-dark" > 浅灰背景颜色。p >
div >
图像
圆角图片
.rounded 类可以让图片显示圆角效果:
< div class = " container" >
< h2> 圆角图片h2 >
< p> .rounded 类可以让图片显示圆角效果:p >
< img src = " https://static.runoob.com/images/mix/cinqueterre.jpg" class = " rounded" alt = " Cinque Terre" width = " 304" height = " 236" >
div >
椭圆图片
.rounded-circle 类可以设置椭圆形图片:
< div class = " container" >
< h2> 椭圆图片h2 >
< p> .rounded-circle 类可以设置椭圆形图片:p >
< img src = " https://static.runoob.com/images/mix/cinqueterre.jpg" class = " rounded-circle" alt = " Cinque Terre" width = " 604" height = " 436" >
div >
缩略图
.img-thumbnail 类用于设置图片缩略图(图片有边框):
< div class = " container" >
< h2> 缩略图h2 >
< p> .img-thumbnail 类用于设置图片缩略图(图片有边框):p >
< img src = " https://static.runoob.com/images/mix/cinqueterre.jpg" class = " img-thumbnail" alt = " Cinque Terre" width = " 404" height = " 336" >
div >
图片对齐方式
使用 .float-right 类来设置图片右对齐,使用 .float-left 类设置图片左对齐:
< div class = " container" >
< h2> 图片对齐方式h2 >
< p> 使用 .float-right 类来设置图片右对齐,使用 .float-left 类设置图片左对齐:p >
< img src = " https://static.runoob.com/images/mix/paris.jpg" class = " float-left" width = " 304" height = " 236" >
< img src = " https://static.runoob.com/images/mix/cinqueterre.jpg" class = " float-right" width = " 304" height = " 236" >
div >
响应式图片
图像有各种各样的尺寸,我们需要根据屏幕的大小自动适应。
我们可以通过在 **** 标签中添加 .img-fluid 类来设置响应式图片。
.img-fluid 类设置了 max-width: 100%; 、 height: auto; :
< div class = " container" >
< h2> 响应式图片h2 >
< p> .img-fluid 类可以设置响应式图片,重置浏览器大小查看效果:p >
< img src = " https://static.runoob.com/images/mix/paris.jpg" class = " img-fluid" >
div >
JavaScript
JAVA的起源故事
JAVA的起源故事
网景公司
5大主流浏览器
有自己研发的内核
JS引擎是单线程
概念
JavaScript 是 Web 的编程语言。是一门客户端脚本语言
运行在客户端浏览器中的。每一个浏览器都有JavaScript的解析引擎
脚本语言:不需要编译,直接就可以被浏览器解析执行
功能:
JavaScript web 开发人员必须学习的 3 门语言中的一门:
1 、HTML 定义了网页的内容
2 、CSS 描述了网页的布局
3 、JavaScript 对网页行为进行编程
ECMAScript :客户端脚本语言的标准
基本语法
与html结合方式:
(1)内部JS:定义
(2)外部JS:定义
注意:1、
2、
使用、输出 标签之间。
< script>
document. getElementById ( "demo" ) . innerHTML = "我的第一段 JavaScript" ;
< / script>
**注释:**旧的 JavaScript 例子也许会使用 type 属性:
**注释:**type 属性不是必需的。JavaScript 是 HTML 中的默认脚本语言。
JavaScript 能够以不同方式“显示”数据:
使用 window. alert ( ) 写入警告框
使用 document. write ( ) 写入 HTML 输出
使用 innerHTML 写入 HTML 元素
使用 console. log ( ) 写入浏览器控制台
innerHTML
如需访问 HTML 元素 ,JavaScript 可使用 document.getElementById(id) 方法。
id 属性定义 HTML 元素。innerHTML 属性定义 HTML 内容:
< ! DOCTYPE html>
< html>
< body>
< h1> 我的第一张网页< / h1>
< p> 我的第一个段落< / p>
< p id= "demo" > < / p>
< script>
document. getElementById ( "demo" ) . innerHTML = 5 + 6 ;
< / script>
< / body>
< / html>
document.write()
出于测试目的,使用 document.write() 比较方便:
< ! DOCTYPE html>
< html>
< body>
< h1> 我的第一张网页< / h1>
< p> 我的第一个段落< / p>
< script>
document. write ( 5 + 6 ) ;
< / script>
< / body>
< / html>
在 HTML 文档完全加载后使用 document.write() 将删除所有已有的 HTML :
< ! DOCTYPE html>
< html>
< body>
< h1> 我的第一张网页< / h1>
< p> 我的第一个段落< / p>
< button onclick= "document.write(5 + 6)" > 试一试< / button>
< / body>
< / html>
document.write() 方法仅用于测试。
window.alert()
您能够使用警告框来显示数据:
< ! DOCTYPE html>
< html>
< body>
< h1> 我的第一张网页< / h1>
< p> 我的第一个段落< / p>
< script>
window. alert ( 5 + 6 ) ;
< / script>
< / body>
< / html>
console.log()
在浏览器中,您可使用 console.log() 方法来显示数据。
请通过 F12 来激活浏览器控制台,并在菜单中选择“控制台”
< ! DOCTYPE html>
< html>
< body>
< h1> 我的第一张网页< / h1>
< p> 我的第一个段落< / p>
< script>
console. log ( 5 + 6 ) ;
< / script>
< / body>
< / html>
数据类型
原始数据类型(基本数据类型)
1️⃣:number :数字。整数/小数/NaN(not a number 一个不是数字的数字)
2️⃣:string :字符串。“abc” “a”
3️⃣:boolean:true 和 false
4️⃣:null :一个对象为空的占位符
5️⃣:undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
Number
JavaScript不区分整数和浮点数 ,统一用Number表示,以下都是合法的Number类型:
123 ;
0.456 ;
1.2345e3 ;
- 99 ;
NaN;
Infinity;
字符串
字符串是以==单引号’或双引号"==括起来的任意文本,比如'abc'
,"xyz"
等等。请注意,''
或""
本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'
只有a
,b
,c
这3个字符。
JavaScript的字符串就是用''
或""
括起来的字符表示。
如果'
本身也是一个字符,那就可以用""
括起来,比如"I'm OK"
包含的字符是I
,'
,m
,空格,O
,K
这6个字符。
如果字符串内部既包含'
又包含"
怎么办?可以用转义字符\
来标识,比如:
'I\'m \"OK\"!' ;
表示的字符串内容是:I'm "OK"!
转义字符\
可以转义很多字符,比如\n
表示换行,\t
表示制表符,字符\
本身也要转义,所以\\
表示的字符就是\
。
ASCII字符可以以\x##
形式的十六进制表示,例如:
'\x41' ;
还可以用\u####
表示一个Unicode字符:
'\u4e2d\u6587' ;
多行字符串
由于多行字符串用\n
写起来比较费事,所以最新的ES6标准新增了一种多行字符串的表示方法,用反引号 \* ... \*
表示:
` 这是一个
多行
字符串 ` ;
┌─────┐ ┌─────┬─────┬─────┬─────┐
│ ESC │ │ F1 │ F2 │ F3 │ F4 │
│ │ │ │ │ │ │
└─────┘ └─────┴─────┴─────┴─────┘
┌─────┬─────┬─────┬─────┬─────┐
│ ~ │ ! │ @ │ # │ $ │
│ ` │ 1 │ 2 │ 3 │ 4 │
├─────┴──┬──┴──┬──┴──┬──┴──┬──┘
│ │ │ │ │
│ tab │ Q │ W │ E │
├────────┴──┬──┴──┬──┴──┬──┘
│ │ │ │
│ caps lock │ A │ S │
└───────────┴─────┴─────┘
模板字符串
要把多个字符串连接起来,可以用+
号连接:
var name = '小明' ;
var age = 20 ;
var message = '你好, ' + name + ', 你今年' + age + '岁了!' ;
alert ( message) ;
操作字符串
字符串常见的操作如下:
var s = 'Hello, world!' ;
s. length;
要获取字符串某个指定位置的字符,使用类似Array的下标操作,索引号从0开始:
var s = 'Hello, world!' ;
s[ 0 ] ;
s[ 6 ] ;
s[ 7 ] ;
s[ 12 ] ;
s[ 13 ] ;
需要特别注意的是 ,字符串是不可变的 ,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果:
var s = 'Test' ;
s[ 0 ] = 'X' ;
alert ( s) ;
JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串
toUpperCase
toUpperCase()
把一个字符串全部变为大写:
var s = 'Hello' ;
s. toUpperCase ( ) ;
toLowerCase
toLowerCase()
把一个字符串全部变为小写:
var s = 'Hello' ;
var lower = s. toLowerCase ( ) ;
lower;
indexOf
indexOf()
会搜索指定字符串出现的位置:
var s = 'hello, world' ;
s. indexOf ( 'world' ) ;
s. indexOf ( 'World' ) ;
substring
substring()
返回指定索引区间的子串:
var s = 'hello, world'
s. substring ( 0 , 5 ) ;
s. substring ( 7 ) ;
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有true
、false
两种值,要么是true
,要么是false
,可以直接用true
、false
表示布尔值,也可以通过布尔运算计算出来:
true ;
false ;
2 > 1 ;
2 >= 3 ;
&&
运算是 与运算,只有所有都为true
,&&
运算结果才是true
:
true && true ;
true && false ;
false && true && false ;
||
运算是 或运算,只要其中有一个为true
,||
运算结果就是true
:
false || false ;
true || false ;
false || true || false ;
!
运算是 非运算,它是一个单目运算符,把true
变成false
,false
变成true
:
! true ;
! false ;
! ( 2 > 5 ) ;
布尔值经常用在条件判断中,比如:
var age = 15 ;
if ( age >= 18 ) {
alert ( 'adult' ) ;
} else {
alert ( 'teenager' ) ;
}
比较运算符
当我们对Number做比较时,可以通过比较运算符得到一个布尔值:
2 > 5 ;
5 >= 2 ;
7 == 7 ;
实际上,JavaScript允许对任意数据类型做比较:
false == 0 ;
false === 0 ;
要特别注意相等运算符==
。JavaScript在设计时,有两种比较运算符:
第一种是==
比较,它会自动转换数据类型 再比较,很多时候,会得到非常诡异的结果;
第二种是===
比较,它不会自动转换数据类型 ,如果数据类型不一致,返回false
,如果一致,再比较。
由于JavaScript这个设计缺陷,不要 使用==
比较,始终坚持使用===
比较。
另一个例外是NaN
这个特殊的Number与所有其他值都不相等,包括它自己:
NaN === NaN ;
唯一能判断NaN
的方法是通过isNaN()
函数:
isNaN ( NaN ) ;
最后要注意浮点数的相等比较:
1 / 3 === ( 1 - 2 / 3 ) ;
null和undefined
null
表示一个“空”的值,它和0
以及空字符串''
不同,0
是一个数值,''
表示长度为0的字符串,而null
表示“空”。
在其他语言中,也有类似JavaScript的null
的表示,例如Java也用null
,Swift用nil
,Python用None
表示。但是,在JavaScript中,还有一个和null
类似的undefined
,它表示==“未定义
”==。
JavaScript的设计者希望用null
表示一个空的值,而undefined
表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用null
。
undefined
仅仅在判断函数参数是否传递的情况下有用。
数组
数组是一组按顺序排列 的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。例如:
[ 1 , 2 , 3.14 , 'Hello' , null , true ] ;
上述数组包含6个元素。数组用[]
表示,元素之间用,
分隔。
另一种创建数组的方法是通过Array()
函数实现:
new Array ( 1 , 2 , 3 ) ;
然而,出于代码的可读性考虑,强烈建议直接使用[]
。
数组的元素可以通过索引来访问。请注意,索引的起始值为0
:
var arr = [ 1 , 2 , 3.14 , 'Hello' , null , true ] ;
arr[ 0 ] ;
arr[ 5 ] ;
arr[ 6 ] ;
对象
JavaScript的对象是一组由键-值组成的无序集合,例如:
var person = {
name: 'Bob' ,
age: 20 ,
tags: [ 'js' , 'web' , 'mobile' ] ,
city: 'Beijing' ,
hasCar: true ,
zipcode: null
} ;
JavaScript对象的键都是字符串类型,值可以是任意数据类型。上述person
对象一共定义了6个键值对,其中每个键又称为对象的属性,例如,person
的name
属性为'Bob'
,zipcode
属性为null
。
要获取一个对象的属性,我们用对象变量.属性名
的方式:
< script>
var person = {
name: 'Bob' ,
age: 20 ,
tags: [ 'js' , 'web' , 'mobile' ] ,
city: 'Beijing' ,
hasCar: true ,
zipcode: null
} ;
document. write ( person. name) ;
document. write ( ' ' ) ;
document. write ( person. zipcode) ;
< / script>
变量
变量在JavaScript中就是用一个变量名表示,变量名是大小写英文、数字、$
和_
的组合,且 不能用数字开头 。变量名也不能是JavaScript的关键字,如if
、while
等。申明一个变量用var
语句,比如:
var a;
var $b = 1 ;
var s_007 = '007' ;
var Answer = true ;
var t = null ;
变量名也可以用中文,但是,请不要给自己找麻烦。
在JavaScript中,使用等号=
对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,但是要注意只能用var
申明一次,
例如:
var a = 123 ;
a = 'ABC' ;
这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
例如Java是静态语言,赋值语句如下:
int a = 123 ;
a = "ABC" ;
和静态语言相比,动态语言更灵活,就是这个原因。
请不要把赋值语句的等号等同于数学的等号。
2、引用数据类型:对象
3、变量
概念:一小块存储数据的内存空间
==语法:var 变量名 = 初始化值;==
typeof 运算符 :获取变量的类型
注:null 运算后得到的是object
4、运算符
1. 一元运算符:只有一个运算数的运算符
* ++ ( -- ) 在前,先自增( 自减) ,再运算
* ++ ( -- ) 在后,先运算,再自增( 自减)
* + ( - ) :正负号
* 注意:在JS 中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换
* 其他类型转number:
* string 转number:按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)
* boolean转number:true 转为1 ,false 转为0
2. 算数运算符
+ - * / % ...
3. 赋值运算符
= += - + ... .
4. 比较运算符
> < >= <= == === ( 全等于)
* 比较方式
1. 类型相同:直接比较
* 字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。
2. 类型不同:先进行类型转换,再比较
* === :全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
5. 逻辑运算符
&& || !
* 其他类型转boolean:
1. number:0 或NaN为假,其他为真
2. string :除了空字符串( "" ) ,其他都是true
3. null & undefined : 都是false
4. 对象:所有对象都为true
6. 三元运算符
? : 表达式
var a = 3 ;
var b = 4 ;
var c = a > b ? 1 : 0 ;
* 语法:
* 表达式? 值1 : 值2 ;
* 判断表达式的值,如果是true 则取值1 ,如果是false 则取值
5、流程控制语句
1. if ... else ...
2. switch :
* 在java中,switch 语句可以接受的数据类型: byte int short char, 枚举( 1.5 ) , String ( 1.7 )
* switch ( 变量) :
case 值:
* 在JS 中, switch 语句可以接受任意的原始数据类型
3. while
4. do ... while
5. for
6、JS特殊语法:
1. 语句以; 结尾,如果一行只有一条语句则 ; 可以省略 ( 不建议)
2. 变量的定义使用var 关键字,也可以不使用
* 用: 定义的变量是局部变量
* 不用:定义的变量是全局变量( 不建议)
7、99乘法表
< script>
for ( var i = 1 ; i <= 9 ; i++ ) {
for ( var j = 1 ; j <= i; j++ ) {
document. write ( i + "×" + j + "=" + ( i* j) + " " ) ;
}
document. write ( ' ' ) ;
}
< / script>
基本对象
Function
函数(方法)对象
1、创建:
1 、 var fun = new Function ( 形式参数列表, 方法体) ;
2 、 function 方法名称 ( 形式参数列表 ) {
方法体
}
3 、 var 方法名 = function ( 形式参数列表 ) {
方法体
}
2、属性: length:代表形参的个数
3、特点:
4、调用: 方法名称(实际参数列表);
标准对象
Date
在JavaScript中,Date
对象用来表示日期和时间。
创建 Date 对象的语法:
var date= new Date ( )
**注释:**Date 对象会自动把当前日期和时间保存为其初始值。
要获取系统当前时间,用:
var date = new Date ( ) ;
date;
date. getFullYear ( ) ;
date. getMonth ( ) ;
date. getDate ( ) ;
date. getDay ( ) ;
date. getHours ( ) ;
date. getMinutes ( ) ;
date. getSeconds ( ) ;
date. getMilliseconds ( ) ;
date. getTime ( ) ;
date. toLocaleString ( )
其他Date对象的方法
注意:JavaScript的月份范围用整数表示是0~11,0
表示一月,1
表示二月……,所以要表示6月,我们传入的是5
!
JavaScript的Date对象月份值从0开始,牢记0=1月,1=2月,2=3月,……,11=12月。
RegExp
1、正则表达式:定义字符串的组成规则
1 、单个字符:[ ]
如:[ a] 、[ ab] 、[ a- zA- Z0 - 9 _]
特殊符号代表特殊含义的单个字符:
\d : 单个数字字符 [ 0 - 9 ]
\w : 单个单词字符 [ a- zA- Z0 - 9 _]
2 、量词符号
? :表示出现0次或1次
* :表示出现0次或多次
+ :表示出现1次或多次
{ m, n} :表示m<= 数量 <= n
m如果缺省:{,n}:最多n次
n如果缺省:{m,}:最少m次
3 、开始结束符号
^ : 开始
$ : 结束
2、正则对象
1 、创建
* var reg = new RegExp ( "正则表达式" ) ;
* var reg = / 正则表达式 / ;
2 、方法
* test ( 参数) :验证指定的字符串是否符合正则定义的规范
预编译
预编译
JS解释器如何找到我们定义的函数和变量?
*通过 **变量对象(Variable Object, VO)*来获取。VO是一个抽象概念的“对象”,它用于存储执行上下文中的:
1. 变量;2. 声明;3. 函数参数 。
函数的VO分为两个阶段——变量初始化和代码执行。在变量初始化阶段,VO按照如下顺序填充:
1. 函数参数(若未传入,初始化该参数值为undefined)
2. 函数声明(若发生命名冲突,会覆盖)
3. 变量声明(初始化变量值为undefined,若发生命名冲突,则忽略)
注意:函数表达式与变量初始化无关。
在变量初始化阶段,需要先对arguments变量进行初始化(激活对象,AO),再把函数体内的变量声明与函数声
明存储在AO内,VO(functionContext) === AO。
在函数执行的前一刻,他创造了一个空间,然后看了一眼函数,把我们马上要用到的 aa 放到了这个空间里面,这个过程就称为预编译
在函数执行之前将函数中的变量、方法收集起来,存放到一个空间中,以便函数在稍后执行时能从这个空间中
拿到函数中需要的变量和方法。而这个空间被称为执行期上下文,也叫活动对象(Activation Object),在后面都
称为 AO,他是一个对象。
总结:
预编译的的过程不是从上到下顺序执行的,并且,函数声明存放进 AO 的顺序在变量声明之后。
预编译发生在函数执行的前一刻!
预编译的过程(预编译四部曲):
1、创建 AO 对象(Activation Object)(执行期上下文)
2、找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
3、将实参值和形参统一
4、找函数声明,函数名作为 AO 属性名,值为函数体
例题1:
写出所有打印结果。
第一步创建 AO 对象
第二步找形参,变量声明,值为 undefined
第三步实参和形参统一
a是形参
第四步找函数声明,值为函数体
然后就是正常执行函数了,最后结果为
注意:var b = function(){} 他不是一个函数声明,是一个变量声明 + 赋值语句
例题2:
< script>
function test ( a ) {
console. log ( a) ;
var a = 123 ;
console. log ( a) ;
function a ( ) { }
console. log ( a) ;
console. log ( b) ;
var b = function ( ) { }
console. log ( b) ;
function d ( ) { }
}
test ( 1 ) ;
< / script>
1 、创建AO 对象
AO {
}
2 、 找形参和变量声明, 将变量和形参名作为AO 属性名, 值为undefined
AO {
a : undefined
b : undefined
}
3 、将实参值和形参统一
AO {
a : 1
b : undefined
}
4 、 在函数体里面找函数声明, 值赋予函数体.
AO {
a : function a ( ) { }
b : function ( ) { }
d : function d ( ) { }
}
全局上下文
GO global object
1、找变量
2、找函数声明
3、执行
var a = 1 ;
function a ( ) {
console. log ( 2 ) ;
}
console. log ( a) ;
输出: 1
1 、创建GO 变量
AO {
}
2 、找变量
AO {
a: undefined ;
}
3 、找函数声明
AO {
a: undefined -- - > function a ( ) { } ;
}
4 、赋值实参
AO {
a: undefined -- - > function a ( ) { } -- - > 1 ;
}
GO === window
< script>
function test ( ) {
console. log ( b) ;
if ( a) {
var b = 2 ;
}
c= 3 ;
console. log ( c) ;
}
var a;
test ( ) ;
a= 1 ;
console. log ( a) ;
< / script>
输出:undefined
3
1
GO = {
a : undefined ,
-- - > 1
test : function test ( ) { }
c: 3
}
AO = {
b : undefined
}
if 语句在预编译前是不执行的,所以b是在AO 的
c= 3 ; 没有var 声明,所以在GO
Global
特点:全局变量,这个Global中封装的方法不需要对象就可以直接调用。
方法名(); 1、方法
encodeURI ( ) : url编码
decodeURI ( ) : url解码
encodeURIComponent ( ) :url编码
decodeURIComponent ( ) :url解码
parseInt ( ) ;
isNaN ( ) ;
eval ( ) ;
encodeURI() 、decodeURI()
encodeURI() 、decodeURI() 案例
URL 编码
传智播客 = % E4 % BC % A0 % E6 % 99 % BA % E6 % 92 % AD % E5 % AE % A2
< script>
var str = "传智播客" ;
var encode = encodeURI ( str) ;
document. write ( encode+ " " ) ;
var decode = decodeURI ( str) ;
document. write ( decode) ;
< / script>
结果:
% E4 % BC % A0 % E6 % 99 % BA % E6 % 92 % AD % E5 % AE % A2
传智播客
parseInt()
parseInt() 将字符串转为数字
var str2 = "234abc" ;
document. write ( parseInt ( str2) ) ;
结果: 234
若数字前面不是数字,即变成NaN
var str2 = "a234abc" ;
document. write ( parseInt ( str2) ) ;
结果:NaN
parseInt(str2,radix)表示进制转换
var str2 = '10' ;
console. log ( parseInt ( str2, 16 ) ) ;
输出: 16
parseFloat
< script>
var str2 = parseFloat ( '3.1415926' ) ;
console. log ( str2) ;
< / script>
输出: 3.1415926
toFixed:保留小数点后几位(四舍五入)
< script>
var str2 = parseFloat ( '3.1415926' ) ;
console. log ( str2. toFixed ( 3 ) ) ;
< / script>
输出: 3.142
isNaN()
isNaN(); //判断一个值是否是NaN
转换为 Number(值) --> 再判断是否为NaN --> 再输出boolean值
< script>
var a = "NaN" ;
document. write ( a== NaN ) ;
document. write ( " " ) ;
document. write ( isNaN ( a) ) ;
< / script>
结果:
false
true
console. log ( isNaN ( 'a' ) ) ;
console. log ( isNaN ( null ) ) ;
console. log ( isNaN ( undefined ) ) ;
输出:true ,false ,true
eval()
eval(); //将JavaScrict 字符串,并把它作为脚本代码来执行。
< script>
var jscode = "alert(123)" ;
eval ( jscode) ;
< / script>
结果:弹出123 窗口
DOM
概念
* 概念: Document Object Model 文档对象模型
* 将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行CRUD 的动态操作
* W3C DOM 标准被分为 3 个不同的部分:
* 核心 DOM - 针对任何结构化文档的标准模型
* Document:文档对象
* Element:元素对象
* Attribute:属性对象
* Text:文本对象
* Comment: 注释对象
* Node:节点对象,其他5 个的父对象
* XML DOM - 针对 XML 文档的标准模型
* HTML DOM - 针对 HTML 文档的标准模型
核心DOM模型
* 核心DOM 模型:
* Document:文档对象
1. 创建 ( 获取) :在html dom模型中可以使用window对象来获取
1. window. document
2. document
2. 方法:
1. 获取Element对象:
1. getElementById ( ) : 根据id属性值获取元素对象。id属性值一般唯一
2. getElementsByTagName ( ) :根据元素名称获取元素对象们。返回值是一个数组
3. getElementsByClassName ( ) : 根据Class属性值获取元素对象们。返回值是一个数组
4. getElementsByName ( ) : 根据name属性值获取元素对象们。返回值是一个数组
2. 创建其他DOM 对象:
createAttribute ( name)
createComment ( )
createElement ( )
createTextNode ( )
3. 属性
* Element:元素对象
1. 获取/ 创建:通过document来获取和创建
2. 方法:
1. removeAttribute ( ) :删除属性
2. setAttribute ( ) :设置属性
* Node:节点对象,其他5 个的父对象
* 特点:所有dom对象都可以被认为是一个节点
* 方法:
* CRUD dom树:
* appendChild ( ) :向节点的子节点列表的结尾添加新的子节点。
* removeChild ( ) :删除(并返回)当前节点的指定子节点。
* replaceChild ( ) :用新节点替换一个子节点。
* 属性:
* parentNode 返回节点的父节点。
Element:元素对象案例
Element: 元素对象案例
方法案例:
1. removeAttribute ( ) :删除属性
2. setAttribute ( ) :设置属性
< body>
< a> 点我试一试< / a>
< input type= "button" id= "btn_set" value= "设置属性" >
< input type= "button" id= "btn_remove" value= "删除属性" >
< script>
var btn_set = document. getElementById ( "btn_set" ) ;
btn_set. onclick = function ( ) {
var element_a = document. getElementsByTagName ( "a" ) [ 0 ] ;
element_a. setAttribute ( "href" , "https://www.baidu.com" ) ;
}
var btn_remove = document. getElementById ( "btn_remove" ) ;
btn_remove. onclick = function ( ) {
var element_a = document. getElementsByTagName ( "a" ) [ 0 ] ;
element_a. removeAttribute ( "href" ) ;
}
< / script>
< / body>
Node节点对象实例
* appendChild ( ) :向节点的子节点列表的结尾添加新的子节点。
* removeChild ( ) :删除(并返回)当前节点的指定子节点。
* replaceChild ( ) :用新节点替换一个子节点。
< ! DOCTYPE html>
< html lang= "en" >
< head>
< meta charset= "UTF-8" >
< meta name= "viewport" content= "width=device-width, initial-scale=1.0" >
< title> Document< / title>
< style>
div {
border: 1 px solid red;
}
#div1 {
width: 200 px;
height: 200 px;
}
#div2 {
width: 100 px;
height: 100 px;
}
#div3 {
width: 100 px;
height: 100 px;
}
< / style>
< / head>
< body>
< div id= "div1" >
< div id= "div2" > div2< / div>
div1
< / div>
< a href= "javascript:void(0);" id= "del" > 删除子节点< / a>
< a href= "javascript:void(0);" id= "add" > 增加子节点< / a>
< script>
var element = document. getElementById ( "del" ) ;
element. onclick = function ( ) {
var div1 = document. getElementById ( "div1" ) ;
var div2 = document. getElementById ( "div2" ) ;
div1. removeChild ( div2) ;
}
var element_add = document. getElementById ( "add" ) ;
element_add. onclick = function ( ) {
var div1 = document. getElementById ( "div1" ) ;
var div3 = document. createElement ( "div" ) ;
div3. setAttribute ( "id" , "div3" ) ;
div1. appendChild ( div3) ;
}
< / script>
< / body>
< / html>
javascript:void(0);
href= ”#”, 包含了一个位置信息. 默认的锚是#top, 也就是网页的上端,当连续快速点击此链接时会导致浏览器巨慢甚至崩溃。而javascript: void ( 0 ) 仅仅表示一个死链接,没有任何信息。所以调用脚本的时候最好用void ( 0 )
href= "#" 与javascript:void (0 )的区别
1 、href= "#" 方法其实也是空连接的意思,但是点击之后会自动跳转到页面的最上面,因为用了这个方法就相当于点击了一个锚记,但是这个锚记又没写ID ,所以就默认跳转到页面顶部。
2 、#可以跳转到设置了id的目的地
3 、javascript: void ( 0 ) 则停留在原地,一动不动,我们称之为“死链接”
当点击超级链接时,什么都不发生
< ! -- 1. 当用户链接时,void ( 0 ) 计算为0 , 用户点击不会发生任何效果 -- >
< a href= "javascript:void(0);" > 单击此处什么都不会发生< / a> < br>
执行void操作符当中的代码
< ! -- 2. 执行 void ( ) 操作符中的代码 -- >
< a href= "javascript:void(alert('还真点啊你,真听话!!!哈哈哈!!!'))" > 点我弹出警告框! ! ! < / a> < br>
< a href= "javascript:void(console.log('还真点啊你,真听话!!!哈哈哈!!!'))" > 点我输出到控制台! ! ! < / a> < br>
计算void操作符当中的算术
< button type= "button" > 点我< / button>
< script type= "text/javascript" >
document. querySelector ( 'button' ) . addEventListener ( 'click' , function ( ) {
var a, b, c, d;
a = void ( b = 2 , c = 3 ) ;
console. log ( 'a => ' + a) ;
console. log ( 'b => ' + b) ;
console. log ( 'c => ' + c) ;
console. log ( 'd => ' + d) ;
} ) ;
< / script>
HTML DOM
* HTML DOM
1. 标签体的设置和获取:innerHTML
2. 使用html元素对象的属性
3. 控制元素样式
1. 使用元素的style属性来设置
如:
div1. style. border = "1px solid red" ;
div1. style. width = "200px" ;
div1. style. fontSize = "20px" ;
2. 提前定义好类选择器的样式,通过元素的className属性来设置其class 属性值。
事件监听机制
https://www.w3school.com.cn/jsref/dom_obj_event.asp
* 概念:某些组件被执行了某些操作后,触发某些代码的执行。
* 事件:某些操作。如: 单击,双击,键盘按下了,鼠标移动了
* 事件源:组件。如: 按钮 文本输入框...
* 监听器:代码。
* 注册监听:将事件,事件源,监听器结合在一起。 当事件源上发生了某个事件,则触发执行某个监听器代码。
常见的事件:
点击事件
1. onclick:单击事件
2. ondblclick:双击事件
焦点事件
1. onblur:失去焦点 -- -- - 一般用于表单验证
2. onfocus: 元素获得焦点。
加载事件
onload:一张页面或一幅图像完成加载。
鼠标事件
1. onmousedown 鼠标按钮被按下。
* 定义方法时,定义一个形参,接受event对象
* event对象的button属性可以获取鼠标按钮键被点击了
2. onmouseup 鼠标按键被松开。
3. onmousemove 鼠标被移动。
4. onmouseover 鼠标移到某元素之上。
5. onmouseout 鼠标从某元素移开。
键盘事件
1. onkeydown 某个键盘按键被按下。
2. onkeyup 某个键盘按键被松开。
3. onkeypress 某个键盘按键被按下并松开。
选择和改变
1. onchange 域的内容被改变。
2. onselect 文本被选中。
表单事件
1. onsubmit 确认按钮被点击。
* 可以阻止表单的提交
* 方法返回false 则表单被阻止提交
2. onreset 重置按钮被点击。
Event对象
Event对象代表事件的状态,比如事件在其中发送的元素,键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!
满足案例要求
事件简单学习
< body>
< img id= "light" src= "img/off.gif" onclick= "fun();" >
< img id= "light2" src= "img/off.gif" >
< script>
function fun ( ) {
alert ( '我被点了' ) ;
alert ( '我又被点了' ) ;
}
function fun2 ( ) {
alert ( '咋老点我?' ) ;
}
var light2 = document. getElementById ( "light2" ) ;
light2. onclick = fun2;
< / script>
< / body>
BOM
概念
Browser Object Model 浏览器对象模型
组成
Window:窗口对象
Navigator:浏览器对象
Screen:显示器屏幕对象
History:历史记录对象
Location:地址栏对象
Window:窗口对象
方法
1. 与弹出框有关的方法:
alert ( ) 显示带有一段消息和一个确认按钮的警告框。
confirm ( ) 显示带有一段消息以及确认按钮和取消按钮的对话框。
* 如果用户点击确定按钮,则方法返回true
* 如果用户点击取消按钮,则方法返回false
prompt ( ) 显示可提示用户输入的对话框。
* 返回值:获取用户输入的值
< script>
var flag = confirm ( "您确定要退出吗?" ) ;
if ( flag) {
alert ( "欢迎再次光临!" ) ;
} else {
alert ( "手别抖" ) ;
}
< / script>
< script>
var result = prompt ( "请输入用户名:" ) ;
alert ( result) ;
< / script>
与打开关闭有关的方法
close ( ) 关闭浏览器窗口。
* 谁调用我 ,我关谁
open ( ) 打开一个新的浏览器窗口
* 返回新的Window对象
< body>
< input id= "openBtn" type= "button" value= "打开一个新窗口" / >
< input id= "closeBtn" type= "button" value= "关闭窗口" / >
< script>
var openBtn = document. getElementById ( 'openBtn' ) ;
var newWindow;
openBtn. onclick = function ( ) {
newWindow = open ( "https://www.baidu.com" ) ;
}
var closeBtn = document. getElementById ( 'closeBtn' ) ;
closeBtn. onclick = function ( ) {
newWindow. close ( ) ;
}
< / script>
< / body>
与定时器有关的方式
setTimeout ( ) 在指定的毫秒数后调用函数或计算表达式。
* 参数:
1. js代码或者方法对象
2. 毫秒值
* 返回值:唯一标识,用于取消定时器
clearTimeout ( ) 取消由 setTimeout ( ) 方法设置的 timeout。
setInterval ( ) 按照指定的周期(以毫秒计)来调用函数或计算表达式。
clearInterval ( ) 取消由 setInterval ( ) 设置的 timeout。
循环定时器
< script>
function fun ( ) {
alert ( 'Boom' ) ;
}
setInterval ( fun, 2000 ) ;
< / script>
轮播图
< body>
< img src= "img/banner_1.jpg" id= "img" width= "100%" >
< script>
var number = 1 ;
function fun ( ) {
number++ ;
if ( number > 3 ) {
number = 1 ;
}
var img = document. getElementById ( "img" ) ;
img. src = "img/banner_" + number + ".jpg" ;
}
setInterval ( fun, 3000 ) ;
< / script>
< / body>
属性
1. 获取其他BOM 对象:
history
location
Navigator
Screen:
2. 获取DOM 对象
document
特点
* Window对象不需要创建可以直接使用 window使用。 window. 方法名 ( ) ;
* window引用可以省略。 方法名 ( ) ;
Location
地址栏对象
1. 创建 ( 获取) :
1. window. location
2. location
2. 方法:
* reload ( ) 重新加载当前文档。刷新
3. 属性
* href 设置或返回完整的 URL 。
reload() 例子:
< body>
< button id= "btn" type= "button" value= "刷新" > 刷新< / button>
< script>
var btn = document. getElementById ( 'btn' ) ;
btn. onclick = function ( ) {
location. reload ( ) ;
}
< / script>
< / body>
href 例子:
< body>
< button id= "goItcast" type= "button" value= "菜鸟教程" > 菜鸟教程< / button>
< script>
var btn1 = document. getElementById ( 'goItcast' ) ;
btn1. onclick = function ( ) {
location. href = "https://www.runoob.com/" ;
}
< / script>
< / body>
自动跳转页面
< style>
p{
text- align: center;
}
span{
color: red;
}
< / style>
< body>
< p> < span id= "time" > 5 < / span> 秒后,页面自动跳转< / p>
< script>
var second = 5 ;
var time = document. getElementById ( "time" ) ;
function showtime ( ) {
second -- ;
if ( second<= 0 ) {
location. href = "https://www.runoob.com/" ;
}
time. innerHTML = second + "" ;
}
setInterval ( showtime, 1000 ) ;
< / script>
< / body>
HTML DOM
https://www.w3school.com.cn/htmldom/dom_intro.asp //W3教程
1、标签体的设置和获取:innerHTML
2、使用html元素对象的属性
3、控制元素样式
控制样式1:使用元素的style属性来设置
< body>
< div id= "div1" >
div
< / div>
< script>
var div1 = document. getElementById ( 'div1' ) ;
div1. onclick = function ( ) {
div1. style. border = '1px solid red' ;
div1. style. fontSize = '50px' ;
div1. style. width = '200px' ;
}
< / script>
< / body>
控制样式2:提前定义好选择器的样式,通过元素的className属性来设置其class属性值
< ! DOCTYPE html>
< html lang= "en" >
< head>
< meta charset= "UTF-8" >
< meta name= "viewport" content= "width=device-width, initial-scale=1.0" >
< title> Document< / title>
< style>
. d2{
border: 1 px solid blue;
width: 100 px;
}
< / style>
< / head>
< body>
< div id= "div2" >
div2
< / div>
< script>
var div2 = document. getElementById ( 'div2' ) ;
div2. onclick = function ( ) {
div2. className= "d2" ;
}
< / script>
< / body>
< / html>
事件委托(事件代理)
概念
事件代理(Event Delegation)又称之为事件委托。是Javascript中常用绑定事件的常用技巧。
“事件代理” 既是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。
事件代理的原理是DOM元素的事件冒泡。
通俗例子:
比如一个宿舍的同学同时快递到了,一种方法就是他们一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个宿舍同学;
在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。
事件委托在Javascript中
比如要给一个dom节点添加一个点击事件,但是现在事件不加在该dom节点本身,而是加在它的父节点身上,利用它父节点触发事件,给该dom节点实现事件效果
实现原理
事件委托是利用事件的冒泡原理来实现的
事件冒泡
事件从最深的节点开始,然后逐步向上传播事件
一个事件触发后,会在子元素和父元素之间传播(propagation)
事件传播分成三个阶段:
冒泡例子:
页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,让里面的ul,li,a实现事件效果,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
利用事件委托的作用
节省资源,提高效率,在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间 如果使用事件委托,则只会与dom节点进行一次交互,有效的减少了和dom交互次数
对于新创建的dom节点,也可以拥有事件
可以大量节省内存占用,减少事件注册
可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
使用场景
重复的给dom节点添加事件
给dom树中尚未创建的元素(动态创建)添加事件
使用js添加事件委托
例子1:
< body>
< ul id = " ul" >
< li> 周一去游玩li >
< li> 周二去上班li >
< li> 周三去休息li >
< li> 周四去吃饭li >
ul >
< script>
var ul = document. querySelector ( "#ul" ) ;
ul. onclick = function ( ) {
console. log ( "快醒醒,每天都要上班的!" )
}
script >
body >
例子1中利用父级ul
做事件处理,当li
被点击时,由于冒泡原理,事件就会冒泡到ul
上,因为ul
上有点击事件,所以事件就会触发。
例子2:事件代码不一样
< body>
< ul id = " ul" >
< li> 周一去游玩li >
< li class = " work-day" > 周二去上班li >
< li> 周三去休息li >
< li> 周四去吃饭li >
ul >
< script>
var ul = document. querySelector ( "#ul" ) ;
ul. onclick = function ( e ) {
var e = event || window. event;
var target = e. srcElement || e. target;
if ( target. className == "work-day" ) {
console. log ( "good boy" )
} else {
console. log ( "快醒醒,每天都要上班的!" )
}
}
script >
body >
例子2中就会针对class属性等于"work-day"的li
元素做出不同的事件,其他事件则为默认事件
jQuery的事件委托
$ ( function ( ) {
$ ( '#ul' ) . on ( 'click' , 'li' , function ( ) {
if ( $ ( this ) . hasClass ( 'work-day' ) ) {
alert ( "good boy" ) ;
} else {
alert ( "快醒醒,每天都要上班的!" ) ;
}
} )
} ) ;
事件委托总结
使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。
事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。
如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。
合理使用事件委托可以帮助我们节省资源,提高效率
也可以给dom中尚未创建的节点添加事件
适合用事件委托的事件:
click
mousedown
mouseup
keydown
keyup
keypress
不适合用事件委托的事件:
mousemove(每次都要计算它的位置,非常不好把控)
focus,blur等(本身就没用冒泡的特性,自然就不能用事件委托了)
XML
概念
Extenside Markup Language 可扩展标记语言
可扩展:标签都是自定义的
功能:存储数据 1、配置文件 2、在网络中传输
xml与html的区别 1、xml标签都是自定义的,html标签是预定义的 2、xml的语法严格,html语法松散 3、xml是存储数据的,html是展示数据的
w3c :万维网联盟
语法
基本语法
1、xml文档后的后缀名 : .xml
2、xml第一行必须定义为文档声明
3、xml文档中有且仅有一个跟标签
4、属性值必须使用引号(单双都可)引起来
5、标签必须正确关闭
6、xml标签名称区分大小写
快速入门
< users>
< user id = ' 1' >
< name> zhangsanname >
< age> 23age >
user >
< user id = ' 2' >
< name> lisaname >
< age> 25age >
user >
users >
JQuery
概念
一个JavaScript框架。简化JS开发
jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。jQuery设计的宗旨 是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优 化HTML文档操作、事件处理、动画设计和Ajax交互。
JavaScript框架:本质上就是一些js文件,封装了js的原生代码而已
jquery-xxx.js 与 jquery-xxx.min.js区别:
jquery-xxx.js:开发版本。给程序员看的,有良好的缩进和注释。体积大一些
jquery-xxx.min.js:生产版本。程序中使用,没有缩进。体积小一些。程序加载更快
JQ 和 JS 转换
JQuery对象和JS对象区别与转换
JQuery对象在操作时,更加方便。
JQuery对象和js对象方法不通用的.
两者相互转换
* jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
* js -- > jq : $(js对象)
例子
< body>
< div id = " div1" > div1...div >
< div id = " div2" > div2...div >
< script>
var divs= document. getElementsByTagName ( "div" ) ;
alert ( divs. length) ;
for ( var i= 0 ; i< divs. length; i++ ) {
$ ( divs[ i] ) . html ( "ccc" ) ;
}
var $divs = $ ( "div" ) ;
alert ( $divs. length) ;
$divs[ 0 ] . innerHTML = "ddd" ;
$divs. get ( 1 ) . innerHTML = "eee" ;
script >
body >
ECMAScript
关键字
ECMAScript关键字
ECMA-262 定义了 ECMAScript 支持的一套关键字(keyword) 。
这些关键字标识了 ECMAScript 语句的开头和/或结尾。根据规定,关键字是保留的,不能用作变量名或函数名。
下面是 ECMAScript 关键字的完整列表:
break
case
catch
continue
default
delete
do
else
finally
for
function
if
in
instanceof
new
return
switch
this
throw
try
typeof
var
void
while
with
**注意:**如果把关键字用作变量名或函数名,可能得到诸如 “Identifier Expected”(应该有标识符、期望标识符)这样的错误消息。
ECMAScript 变量
ECMAScript 保留字
基本语法
NaN (not a number)- > 数字类型
infinity (无穷大) - > 数字类型
(1 / 0 )- > 无穷小
- infinity (无穷小) - > 数字类型
(- 1 / 0 )- > 无穷小
undefined 、NaN 、null 、“ ”、0、false 是假,其余为真
object对象
属性名/键名: 属性值/键值
var person = {
name: '小赵' ,
age: 18 ,
height: 160 ,
weight: 40 ,
job: 'student'
}
person. name = '小黄' ;
console. log ( person) ;
输出:{ name: "小黄" , age: 18 , height: 160 , weight: 40 , job: "student" }
typeof
console. log ( typeof ( num) ) ;
输出:undefined
console. log ( typeof ( typeof ( num) ) ) ;
输出:string
总结:typeof 后再有一个typeof 那么它的类型一定是 String。
arguments
JavaScript还有一个免费赠送的关键字arguments
,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments
类似Array
但它不是一个Array
:
function foo ( x ) {
console. log ( 'x = ' + x) ;
for ( var i= 0 ; i< arguments. length; i++ ) {
console. log ( 'arg ' + i + ' = ' + arguments[ i] ) ;
}
}
foo ( 10 , 20 , 30 ) ;
利用arguments
,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值:
function abs ( ) {
if ( arguments. length === 0 ) {
return 0 ;
}
var x = arguments[ 0 ] ;
return x >= 0 ? x : - x;
}
abs ( ) ;
abs ( 10 ) ;
abs ( - 9 ) ;
隐式类型转换
< script>
var a = '123' ;
a++ ;
console. log ( a) ;
< / script>
输出:: 124
< script>
var str2 = 'a' + 1 ;
console. log ( str2) ;
< / script>
输出:a1
< script>
var str2 = '7' * 2 ;
console. log ( str2) ;
< / script>
输出:14
< script>
var a = undefined == null ;
console. log ( a) ;
< / script>
输出:true
undefined 和 null 既不大于0 也不小于0 也不等于0
但是他俩== 为true
NaN 不等于 NaN
实参求和
< script>
function sum ( ) {
var a = 0 ;
for ( var i = 0 ; i < arguments. length; i++ ) {
a += arguments[ i] ;
}
console. log ( a) ;
}
sum ( 1 , 2 , 3 , 4 , 5 ) ;
< / script>
输出: 15
< script>
function test ( a, b ) {
b = 3 ;
console. log ( arguments[ 1 ] ) ;
}
test ( 1 ) ;
< / script>
输出:undefined
在实参里传了值的,我们可以在函数内部去修改参数值,
但是在实参里并没有传入值,而你给形参赋值了,是没有用的
作用域
对象 —>有些属性是我们无法访问的,JS引擎内部固有的隐式属性
[[scope]]
1 、函数创建时,生成的一个JS 内部的隐式属性
2 、函数存储作用域链的容器,作用域链
AO/GO
AO:函数的执行期上下文
GO:全局的执行期上下文
函数执行完成以后,AO是要销毁的
AO是一个即时的存储容器
只要函数被定义时,就生成作用域和相应的作用域链 GO
只要函数被执行那一刻,就生成AO
function a ( ) {
function b ( ) {
function c ( ) {
}
c ( ) ;
}
b ( ) ;
}
a ( ) ;
闭包
闭包就是能够读取其他函数内部变量的函数
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成**“定义在一个函数内部的函数”**。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
当内部函数被返回到外部并保存时,一定会产生闭包,闭包会产生原来的作用域链不释放,过渡的闭包可能会导致内存泄漏或加载过慢
结论:闭包找到的是同一地址中父级函数中对应变量最终的值
学习闭包
test1被执行的时候,test2被定义,所以test2的作用域以及作用域链和test1执行时的作用域以及作用域链是一致的
当执行return test2;时
(test2被抛到外面去,变成了全局。test2里有test1的AO,所以test1的AO不能被销毁,反而被保留。)
所以 var test3 = test1();的test1()是test2。
(test1()函数被return test2;的test2赋值,test1();存的就是test2)
当执行test3();时
当test3执行结束时
闭包例子
闭包例子:
var i = 0 ; function outerFn ( ) {
function outerFn ( ) { var i = 0 ;
function innnerFn ( ) { function innnerFn ( ) {
i++ ; i++ ;
console. log ( i) ; console. log ( i) ;
} }
return innnerFn; return innnerFn;
} }
var inner1 = outerFn ( ) ; var inner1 = outerFn ( ) ;
var inner2 = outerFn ( ) ; var inner2 = outerFn ( ) ;
inner1 ( ) ; inner1 ( ) ;
inner2 ( ) ; inner2 ( ) ;
inner1 ( ) ; inner1 ( ) ;
inner2 ( ) ; inner2 ( ) ;
输出:1 2 3 4 输出:1 1 2 2
立即执行函数
立即执行函数 - 初始化函数
(IIFE - immediately-invoked function expression)
一定是表达式才能被执行符号执行
1 、
( function ( ) {
} ( ) ) ;
-- -- -- -- -- -- -- -- -- -- --
2 、
( function test ( ) {
} ) ( ) ;
=== === === === === === === =
function test ( ) {
}
test ( ) ;
3 、
var test = function ( ) {
console. log ( ) ;
} ( ) ;
函数声明变成表达式的方法 + - ! || &&
1 && function test ( ) {
console. log ( 1 ) ;
} ( ) ;
例子:点击1 ~ 5然后返回 0~4
< body>
< ul>
< li> 1 < / li>
< li> 2 < / li>
< li> 3 < / li>
< li> 4 < / li>
< li> 5 < / li>
< / ul>
< script>
var oli = document. querySelectorAll ( 'li' ) ;
for ( var i = 0 ; i < oli. length; i++ ) {
oli[ i] . onclick = function ( ) {
console. log ( i) ;
}
}
< / script>
< / body>
输出:点击的都是5
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
< body>
< ul>
< li> 1 < / li>
< li> 2 < / li>
< li> 3 < / li>
< li> 4 < / li>
< li> 5 < / li>
< / ul>
< script>
var oli = document. querySelectorAll ( 'li' ) ;
for ( var i = 0 ; i < oli. length; i++ ) {
( function ( j ) {
oli[ j] . onclick = function ( ) {
console. log ( j) ;
}
} ) ( i) ;
}
< / script>
< / body>
输出:点击1 ~ 5 然后返回 0 ~ 4
对象
对象字面量,对象直接量
例子:
删除对象可以用delete +键值.对象;
删除函数要用delete + 键值.函数名;(不用加括号)
< script>
var teacher = {
name: '张三' ,
age: 18 ,
sex: 'male' ,
height: 176 ,
teach : function ( ) {
console. log ( 'I am teaching JavaScript' ) ;
} ,
eat : function ( ) {
console. log ( 'I am having dinner' ) ;
}
}
teacher. address = "云浮" ;
teacher. drink = function ( ) {
console. log ( 'I am drinking beer' ) ;
}
delete teacher. address;
delete teacher. drink;
teacher. name = "小赵" ;
console. log ( teacher. name) ;
console. log ( teacher) ;
< / script>
构造函数
系统自带的构造函数Object
< script>
var obj = new Object ( ) ;
obj. name = '小赵' ;
obj. sex = 'female' ;
console. log ( obj) ;
< / script>
自定义构造函数
1、
< script>
function Teacher ( ) {
this . name = "小赵" ;
this . sex = "male" ;
this . smoke = function ( ) {
console. log ( "smoking" ) ;
}
}
var teacher = new Teacher ( ) ;
< / script>
2、
< script>
function Teacher ( name, sex ) {
this . name = name;
this . sex = sex;
this . smoke = function ( ) {
console. log ( "smoking" ) ;
}
}
var teacher1 = new Teacher ( '小赵' , '女' ) ;
var teacher2 = new Teacher ( '小黄' , '男' ) ;
console. log ( teacher1) ;
console. log ( teacher1) ;
< / script>
3、常用
< script>
function Teacher ( opt ) {
this . name = opt. name;
this . sex = opt. sex;
this . smoke = function ( ) {
console. log ( "smoking" ) ;
}
}
var teacher1 = new Teacher ( {
name: '小赵' ,
sex: 'female'
} ) ;
var teacher2 = new Teacher ( {
name: '小黄' ,
sex: 'male'
} ) ;
console. log ( teacher1) ;
console. log ( teacher1) ;
< / script>
包装类
原始值没有自己的方法和属性
var a = 123 ;
a. len = 3 ;
console. log ( a. len) ;
输出:undefined
原因:没有地方保存,然后被删除了
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
var a = new Number ( 123 ) ;
a. len = 3 ;
console. log ( a. len) ;
输出:3
原因:因为a已经是对象了
var str = 'abc' ;
console. log ( str. length) ;
===
console. log ( new String ( str) . length) ;
数组截断法
var arr = [ 1 , 2 , 3 , 4 , 5 ] ;
arr. length = 3 ;
console. log ( arr) ;
输出:[ 1 , 2 , 3 ]
原型
JavaScript原型
原型和原型链
yuanxing
prototype
原型的英文应该叫做 prototype
,任何一个对象都有原型,我们可以通过非标准属性 __proto__
来访问一个对象的原型:原型是属于实例化对象的,而不是构造函数的
console. log ( { } . __proto__) ;
function Student ( name, grade ) {
this . name = name;
this . grade = grade;
}
const stu = new Student ( 'xiaoMing' , 6 ) ;
console. log ( stu. __proto__) ;
在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。
function Person ( age ) {
this . age = age
}
Person . prototype. name = 'kavin'
var person1 = new Person ( )
var person2 = new Person ( )
console. log ( person1. name)
console. log ( person2. name)
上述例子中,函数的prototype指向了一个对象,而这个对象正是调用构造函数时创建的实例的原型,
也就是person1和person2的原型。
原型的概念 :每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我
们所说的原型,每一个对象都会从原型中“继承”属性 :意思是所有被该构造函数构造出的对象都可以继承原型上的属性和方法 。
一般情况下需要把参数写死的,就首选prototype,调用的时候就继承即可
function Handphone ( color, brand ) {
this . color = color;
this . brand = brand;
this . screen = '18:9' ;
this . system = 'Android' ;
}
Handphone . prototype. rom = '64G' ;
Handphone . prototype. ram = '6G' ;
Handphone . prototype. screen = '16:9' ;
var hp1 = new Handphone ( 'red' , '小米' ) ;
var hp2 = new Handphone ( 'black' , 'HUAWEI' ) ;
console. log ( hp1. rom) ;
console. log ( hp2. ram) ;
console. log ( hp1. screen) ;
输出: 64 G
6 G
18 : 9
所以一般情况下是这样写的
function Handphone ( color, brand ) {
this . color = color;
this . brand = brand;
}
Handphone . prototype = {
rom: '64G' ,
ram: '6G' ,
screen: '16:9' ,
system: 'Android' ,
call : function ( ) {
console. log ( 'I am calling somebody' ) ;
}
}
var hp1 = new Handphone ( 'red' , '小米' ) ;
var hp2 = new Handphone ( 'black' , 'HUAWEI' ) ;
hp2 . call ( ) ;
输出:I am calling somebody
构造函数和实例原型之间的关系:
__proto__
__proto__
是非标准属性,这是每个对象(除null外)都会有的属性这个属性会指向该对象的原型。
访问一个对象的原型,可以使用 ES6 新增的 Reflect.getPrototypeOf()
或者 Object.getPrototypeOf()
方法。
function Person ( ) {
}
var person = new Person ( ) ;
console. log ( person. __proto__ === Person . prototype) ;
function Car ( ) {
}
Car . prototype. name = 'Benz' ;
var car = new Car ( ) ;
console. log ( car) ;
Car . prototype. name = 'Benz' ;
function Car ( ) { }
var car = new Car ( ) ;
Car . prototype = {
name: 'Mazda'
}
console. log ( car) ;
Car . prototype. name = 'Benz' ;
function Car ( ) { }
Car . prototype = {
name: 'Mazda'
}
var car = new Car ( ) ;
console. log ( car) ;
constructor
在 JavaScript 中,函数都可以用作构造器 。构造器我们也可以称之为类
constructor —> 指向构造函数本身
constructor是可以修改的
function Handphone ( color, brand ) {
this . color = color;
this . brand = brand;
}
console. log ( Handphone . prototype) ;
输出:constructor: ƒ Handphone ( color, brand)
function Person ( ) {
}
console. log ( Person=== Person . prototype. constructor)
function Person ( ) {
}
var person = new Person ( ) ;
console. log ( person. __proto__ == Person . prototype)
console. log ( Person . prototype. constructor == Person)
console. log ( Object. getPrototypeOf ( person) === Person . prototype)
原型链
沿着_proto_
去找原型里的属性,一层一层地去继承原型的属性的这条链条叫做原型链
< script>
Professor . prototype. tSkill = 'JAVA' ;
function Professor ( ) { }
var professor = new Professor ( ) ;
Teacher . prototype = professor;
function Teacher ( ) {
this . mSkill = 'JS/JQ' ;
}
var teacher = new Teacher ( ) ;
Student . prototype = teacher;
function Student ( ) {
this . pSkill = 'HTML/CSS' ;
}
var student = new Student ( ) ;
console. log ( student) ;
< / script>
原型链的顶端是Object.prototype
Object.prototype
原型的属性里面保存了一个toString
的方法
原始值不能修改,引用值可以修改
< script>
var obj1 = { } ;
console. log ( obj1) ;
var obj2 = new Object ( ) ;
console. log ( obj2) ;
function Obj ( ) { }
var obj3 = new Obj ( ) ;
console. log ( obj3) ;
< / script>
上面两个自变量构造和系统内置的Object 构造器都是指向Object
而自己定义的构造函数是指向是自定义的构造函数
原型的原型它的构造器一定是指向系统自带的Object构造函数
既原型的原型是由系统自带的Object构造出来的
创建对象
Object.create(对象,null)
这个只能填对象或者null,不能不填
可以自定义创建原型
< script>
var test = {
num: 2
}
var obj1 = Object. create ( test) ;
console. log ( obj1) ;
< / cript>
创建空对象
< script>
var obj1 = Object. create ( null ) ;
console. log ( obj1) ;
obj1. num = 1 ;
var obj2 = Object. create ( obj1) ;
console. log ( obj2) ;
< / script>
不是所有的对象都继承于Object.prototype
< script>
var obj1 = Object. create ( null ) ;
console. log ( obj1) ;
obj1. num = 1 ;
< / script>
包装类就是Object create(Object prototype)
toString
原型方法的重写
call/apply
改变this
的指向
< script>
function Car ( brand, color ) {
this . brand = brand;
this . color = color;
}
var newCar = { } ;
Car . call ( newCar, 'Benz' , 'red' ) ;
console. log ( newCar) ;
< / script>
apply和call差不多,只是要用数组(arguments)
Car . apply ( newCar, [ 'Benz' , 'red' ] ) ;
构造函数通过实例化了以后的返回值return 是this
而普通函数没写return值时,默认返回undefined
例子:改变this指向
< script>
function Person ( ) {
this . name = '张三' ;
this . age = 18 ;
}
function Programmer ( ) {
Person . apply ( this ) ;
this . work = 'Programming'
}
var p = new Programmer ( ) ;
console. log ( p) ;
< / script>
有参数的情况下:
圣杯模式
< / script>
function Teacher ( ) {
this . name = 'ZMY' ;
this . tSkill = 'JAVA' ;
}
Teacher. ptototype = {
pSkill: 'JS/SQ'
}
var t = new Teacher ( ) ;
console. log ( t) ;
function Student ( ) {
this . name = "HFH" ;
}
function Buffer ( ) { }
Buffer . prototype = Teacher . prototype;
var buffer = new Buffer ( ) ;
Student . prototype = buffer;
Student . prototype. age = 18 ;
var s = new Student ( ) ;
console. log ( s) ;
< / script>
创建一个Buffer函数,把Teacher的protoype赋值给Buffer的prototype,然后实例化Buffer即可
CSS的圣杯模式/双飞翼
企业级写法
< script>
var inherit = ( function ( ) {
var Buffer = function ( ) { }
return function ( Target, Origin ) {
Buffer . prototype = Origin . prototype;
Target . prototype = new Buffer ( ) ;
Target . prototype. constructor = Target;
Target . prototype. super_class = Origin;
}
} ) ( ) ;
Teacher . prototype. name = 'Mr.Zhang' ;
function Teacher ( ) { }
function Student ( ) { }
function Buffer ( ) { }
inherit ( Student, Teacher) ;
var s = new Student ( ) ;
var t = new Teacher ( ) ;
console. log ( s) ;
console. log ( t) ;
< / script>
模块化开发
在公司里一般都会用这种协同开发模块的方法,每个人负责不一样的模块,然后需要执行的方法
统一放进function init(){}里,然后在全局用window去执行
把功能封装到了自启动函数,然后赋给了一个变量,这个全局的变量包含了里面的所有方法,
只要执行这个全局变量,则返回出去的方法都会被执行
< script>
window. onload = function ( ) {
init ( ) ;
}
function init ( ) {
initCompute ( ) ;
console. log ( '-----------------------' ) ;
initFunctions ( ) ;
}
var initCompute = ( function ( ) {
var a = 1 ,
b= 2 ;
function add ( ) {
console. log ( a + b) ;
}
function minus ( ) {
console. log ( a - b) ;
}
return function ( ) {
add ( ) ;
minus ( ) ;
}
} ) ( ) ;
var initFunctions = ( function ( ) {
var a = 2 ,
b = 4 ;
function mul ( ) {
console. log ( a * b) ;
}
function div ( ) {
console. log ( a / b) ;
}
return function ( ) {
mul ( ) ;
div ( ) ;
}
} ) ( ) ;
; ( function ( ) {
var Slider = function ( opt ) { }
Slider . prototype = {
}
window. Slider = Slider;
} ) ( ) ;
var slider = new Slider ( {
} ) ;
< / script>
hasOwnProperty
JavaScript hasOwnProperty()
方法是 Object 的原型方法(也称实例方法),它定义在 Object.prototype
对象之上,所有 Object 的实例对象都会继承 hasOwnProperty()
方法。
hasOwnProperty()
方法用来检测一个属性是否是对象的自有属性 ,而不是从原型链继承的
如果该属性是自有属性,那么返回 true,否则返回 false
hasOwnProperty()
方法不会检测对象的原型链,只会检测当前对象本身 ,只有当前对象本身存在该属性时才返回 true
排除原型
hasOwnProperty() 的语法格式如下:
object. hasOwnProperty ( propertyName) ;
参数说明:propertyName 参数表示要检测的属性名称。
返回值:返回一个布尔值。如果 propertyName 是自有属性,那么返回 true,否则返回 false。
例如,在下面自定义类型中,this.name 就表示对象的自有属性,而原型对象中的 name 属性就是继承属性。
function F ( ) {
this . name = "自有属性" ; }
F . prototype. name = "继承属性" ;
}
var f = new F ( ) ;
console. log ( f. hasOwnProperty ( "name" ) ) ;
console. log ( f. name) ;
凡是构造函数的原型属性(原型对象包含的属性),都是继承属性,使用 hasOwnProperty() 方法检测时,都会返回 false。但是,对于原型对象本身来说,这些原型属性又是原型对象的自有属性,所以返回值又是 true。
hasOwnProperty() 方法只能判断指定对象中是否包含指定名称的属性,无法检查对象原型链中是否包含某个属性,所以能够检测出来的属性必须是对象成员。
hasOwnProperty() 方法所能检测的属性范围。
var o = {
o1: {
o2: {
name: 1
}
}
} ;
console. log ( o. hasOwnProperty ( "o1" ) ) ;
console. log ( o. hasOwnProperty ( "o2" ) ) ;
console. log ( o. o1. hasOwnProperty ( "o2" ) ) ;
console. log ( o. o1. hasOwnProperty ( "name" ) ) ;
console. log ( o. o1. o2. hasOwnProperty ( "name" ) ) ;
例子
< script>
var obj = {
name: '小赵' ,
age: 17
}
function Car ( ) {
this . brand = 'Benz' ;
this . color = 'red' ;
}
Car . prototype = {
lang: 5 ,
width: 2.5
}
Object . prototype. name = 'Object' ;
var car = new Car ( ) ;
for ( var key in car) {
if ( car. hasOwnProperty ( key) ) {
console. log ( car[ key] ) ;
}
}
< / script>
判断是否为Array数组
var a = [ ] ;
console. log ( a. constructor) ;
console. log ( a instanceof Array ) ;
var str = Object . prototype. toString . call ( a) ;
if ( str === '[object Array]' ) {
console. log ( '是数组' ) ;
} else {
console. log ( '不是数组' ) ;
}
instanceof
判断它是否是由当前构造函数构造出来的
< script>
function Car ( ) { }
var car = new Car ( ) ;
function Person ( ) { }
var p = new Person ( ) ;
console. log ( car instanceof Car ) ;
console. log ( p instanceof Car ) ;
console. log ( car instanceof Object ) ;
console. log ( [ ] instanceof Array ) ;
console. log ( [ ] instanceof Object ) ;
console. log ( { } instanceof Object ) ;
< / script>
面试或者笔试会问到
js机制
car.key -->car['key']
var car = {
brand: 'Benz' ,
color: 'red' ,
displacement: '3.0' ,
lang: '5' ,
width: '2.5'
}
for ( var key in car) {
console. log ( key + ':' + car[ key] ) ;
}
var arr = [ 1 , 2 , 3 , 4 , 5 ] ;
for ( var i in arr) {
console. log ( arr[ i] ) ;
}
结果:
this
全局this -->window
预编译函数this -->window
apply / call 改变this指向
构造函数的this指向实例化对象
callee
function test1 ( ) {
console. log ( arguments. callee) ;
function test2 ( ) {
console. log ( arguments. callee) ;
}
test2 ( ) ;
}
test1 ( ) ;
结果:
var sum = ( function ( n ) {
if ( n <= 1 ) {
return 1 ;
}
return n + arguments. callee ( n - 1 ) ;
} ) ( 100 ) ;
console. log ( sum) ;
caller
谁调用了那个函数,就返回调用者函数
返回当前被调用函数的函数引用
caller只有函数被调用了才能用
test1 ( ) ;
function test1 ( ) {
test2 ( ) ;
}
function test2 ( ) {
console. log ( test2. caller) ;
}
结果:
作业
插件
需求:写一个插件,任意传两个数字, 调用插件内部方法可进行加减乘除功能
( function ( ) {
var Compute = function ( ) { }
Compute . prototype = {
puls : function ( a, b ) {
return a + b;
} ,
minus : function ( a, b ) {
return a - b;
} ,
mul : function ( a, b ) {
return a * b;
} ,
div : function ( a, b ) {
return a / b;
}
}
window. Compute = Compute;
} ) ( ) ;
var compute = new Compute ( ) ;
var res = compute. puls ( 1 , 3 ) ;
console. log ( res) ;
插件的标配
; ( function ( ) {
var Tab = function ( opt ) {
}
Tab . prototype = {
}
window. Tab = Tab;
} ) ( ) ;
需求:用call或者apply写两个构造函数,用person()函数借用Car()函数的属性和方法
写一个“年龄为多少岁姓名为什么的人买了一辆什么颜色的什么牌子的车”
< script type= "text/javascript" >
function Car ( brand, color ) {
this . brand = brand;
this . color = color;
this . info = function ( ) {
return '的人买了一辆' + color + '的' + brand + '车' ;
}
}
function Person ( opt ) {
Car . apply ( this , [ opt. brand, opt. color] ) ;
this . name = opt. name;
this . age = opt. age;
this . say = function ( ) {
console. log ( '一个年龄为' + this . age + '岁,姓名叫' + this . name +
this . info ( ) ) ;
}
}
var person = new Person ( {
brand: 'Benz' ,
color: '红色' ,
age: 18 ,
name: '小红枣'
} ) ;
person. say ( ) ;
< / script>
面试题
2020年知乎前端面试题
1、
if ( 1 + 5 * '3' === 16 ) {
console. log ( '通过了' ) ;
} else {
console. log ( '未通过' ) ;
}
输出:通过了
2、
console. log ( ! ! ' ' + ! ! '' - ! ! false || '未通过' ) ;
输出: 1
' ' 是1 ,'' 是0
3、
window. a || ( window. a = '1' ) ;
console. log ( window. a) ;
输出: 1
括号的优先级最高,所以先赋值给window. a ( 1 ) 再做|| 运算
4、
function test ( ) {
var arr = [ ] ;
var i = 0 ;
for ( ; i < 10 ; ) {
arr[ i] = function ( ) {
document. write ( i + " " ) ;
}
i++ ;
}
return arr;
}
var myArr = test ( ) ;
for ( var j = 0 ; j < 10 ; j++ ) {
myArr[ j] ( ) ;
}
输出:10 10 10 10 10 10 10 10 10 10
5、
< script>
var fn = (
function test1 ( ) {
return 1 ;
} ,
function test2 ( ) {
return '2' ;
}
) ( ) ;
console. log ( typeof ( fn) ) ;
< / script>
输出:string
原因:括号的逗号运算是返回最后一个
fn = ( test1 ( ) , test2 ( ) ) -- - > fn = ( test2 ( ) ) ( ) ;
6、
< script>
var a = 10 ;
if ( function b ( ) { } ) {
a += typeof ( b) ;
}
console. log ( a) ;
< / script>
输出: 10 undefined
原因:判断if ( function b ( ) { } ) 是否为true ,是往下执行
( function b ( ) { } ) 是表达式,表达式忽略函数名,所以函数b ( ) 不存在了,即为undefined
7、
< script>
var name = 'languiji' ;
name += 10 ;
var type = typeof ( name) ;
'string'
if ( type. length === 6 ) {
type. text = 'string' ;
}
console. log ( type. text) ;
< / script>
输出: undefined
解决方法:把var type = typeof ( name) ;
变成 var type = new String ( typeof ( name) ) ;
输出:string
8、
< script>
var x = 1 ,
y = z = 0 ;
function add ( n ) {
return n = n + 1 ;
}
y = add ( x) ;
function add ( n ) {
return n = n + 3 ;
}
z = add ( x) ;
console. log ( x, y, z) ;
< / script>
输出:1 , 4 , 4
预编译:GO {
x= 1 ,
y= 0 ,
z= 0 ,
add : function add ( n ) { return n = n+ 1 } -- - > { return n = n+ 3 }
}
9、
< script>
function foo ( x ) {
console. log ( arguments) ;
return x;
}
foo ( 1 , 2 , 3 , 4 , 5 ) ;
function foo1 ( x ) {
console. log ( arguments) ;
return x;
} ( 1 , 2 , 3 , 4 , 5 ) ;
( function foo2 ( x ) {
console. log ( arguments) ;
return x;
} ) ( 1 , 2 , 3 , 4 , 5 ) ;
< / script>
输出:只有1 ,3 能输出1 ,2 ,3 ,4 ,5
2 不行,因为函数表达式后面不能跟执行符号
10、
< script>
function b ( x, y, a ) {
a = 10 ;
console. log ( arguments[ 2 ] ) ;
}
b ( 1 , 2 , 3 ) ;
< / script>
输出: 10
原因:映射关系,先把实参a= 3 赋值给arguments[ 2 ] ,然后形参a= 10 再赋值给arguments
11、原型链的顶端是什么?
答:Object.prototype
12、去除数组中指定元素的方法
比如数组 arr = [3,0,11,0,3,0,66];
var arr = [ 3 , 0 , 11 , 0 , 3 , 0 , 66 ] ;
var newArry = [ ] ;
for ( var i = 0 ; i < arr. length; i++ ) {
if ( arr[ i] != 3 ) {
newArry. push ( arr[ i] ) ;
}
}
console. log ( newArry) ;
var arr = [ 3 , 0 , 11 , 0 , 3 , 0 , 66 ] ;
for ( var i = 0 ; i < arr. length; i++ ) {
if ( arr[ i] == 0 ) {
arr. splice ( i, 1 ) ;
}
}
console. log ( arr) ;
情况二:如果去除指定元素在数组中连续出现几个,不进行处理会存在删漏掉的情况
原因:在循环遍历的时候,i是元素的下标值,删除数组中某个元素的时候,循环i的值不变,但是里面的元素少了,相对应的元素就会向前靠,这样就会漏掉相邻的需要删除的元素;用方法二和方法三,就会避免出现这个问题,强力推荐方法三。
比如数组:arr = [3, 7, 11, 0, 0, 0, 3, 0, 55]
var arr = [ 3 , 7 , 11 , 0 , 0 , 0 , 3 , 0 , 55 ] ;
var newArry = [ ] ;
for ( var i = 0 ; i < arr. length; i++ ) {
if ( arr[ i] != 0 ) {
newArry. push ( arr[ i] ) ;
}
}
console. log ( newArry) ;
var arr = [ 3 , 7 , 11 , 0 , 0 , 0 , 3 , 0 , 55 ] ;
for ( var i = arr. length- 1 ; i >= 0 ; i-- ) {
if ( arr[ i] == 0 ) {
arr. splice ( i, 1 ) ;
}
}
console. log ( arr) ;
var arr = [ 3 , 7 , 11 , 0 , 0 , 0 , 3 , 0 , 55 ]
for ( var i = 0 ; i < arr. length; i++ ) {
if ( arr[ i] == 0 ) {
arr. splice ( i, 1 ) ;
i-- ;
}
}
console. log ( arr) ;
13、
实现一维数组变二维数组,[1,2,3,4,5,6,7,8]变为[[1,2,3],[4,5,6],[7,8]]
Math.ceil()
函数返回大于或等于一个给定数字的最小整数。
< script type= "text/javascript" >
var num = 3 ;
var arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
var Arr = new Array ( Math. ceil ( arr. length / num) ) ;
for ( var i = 0 ; i < Arr. length; i++ ) {
Arr[ i] = new Array ( ) ;
for ( var j = 0 ; j < num; j++ ) {
Arr[ i] [ j] = '' ;
}
}
for ( var i = 0 ; i < arr. length; i++ ) {
Arr[ parseInt ( i / num) ] [ i % num] = arr[ i] ;
}
console. log ( Arr) ;
< / script>
< script type= "text/javascript" >
let baseArray = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
let len = baseArray. length;
let n = 3 ;
let lineNum = len % 3 === 0 ? len / 3 : Math. floor ( ( len / 3 ) + 1 ) ;
let res = [ ] ;
for ( let i = 0 ; i < lineNum; i++ ) {
let temp = baseArray. slice ( i * n, i * n + n) ;
res. push ( temp) ;
}
console. log ( res) ;
< / script>
14、
function foo ( ) {
bar . apply ( null , arguments) ;
}
function bar ( ) {
console. log ( arguments) ;
}
foo ( 1 , 2 , 3 , 4 , 5 )
结果 :
15、JS的typeof可能返回的值有哪些?
object ( null ) / boolean / number / string / undefined / function
16、
console. log ( undefined == null ) ;
console. log ( undefined === null ) ;
console. log ( isNaN ( '100' ) ) ;
console. log ( parseInt ( '1a' ) == 1 ) ;
结果:
true
false
false
true
isNaN -- - > var num = Number ( '100' ) ;
console. log ( isNaN ( num) ) ;
NaN 不等于任何值,包括它自己
17、
{ } == { }
结果:false
原因:存在于不同的空间,地址不一样
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -
var obj = { }
结果:undefined
obj1 = obj
结果:{ }
obj == obj1
结果:true
var a = '1' ;
function test ( ) {
var a = '2' ;
this . a = '3' ;
console. log ( a) ;
}
test ( ) ;
new test ( ) ;
console. log ( a) ;
var a = 5 ;
function test ( ) {
a = 0 ;
console. log ( a) ;
console. log ( this . a) ;
var a;
console. log ( a) ;
}
test ( ) ;
new test ( ) ;
结果:
0
5
0
0
undefined
0
18、
axios面试大概会问什么?
(1)为什么axios既可以当函数调用,也可以当对象使用
axios本质是函数,赋值了一些别名方法,比如get、post方法,可被调用
对象调用是因为获取的是Axios类的实例
最终调用的还是Axios.prototype.request函数。
(2)简述axios调用流程。
创建axios实例
实际调用的是Axios.prototype.request方法
最终返回promise链式调用结果
请求是在dispatchRequest中派发的,浏览器端本质是xhr
(3)聊一聊拦截器?
axios.interceptors.request.use添加请求成功和失败拦截器函数
axios.interceptors.response.use添加响应成功和失败拦截器函数
在Axios.prototype.request函数组成promise链式调用时, Interceptors.protype.forEach遍历请求和响应拦截器
通过unshift和push添加到真正发送请求dispatchRequest的两端,从而做到请求前拦截和响应后拦截
拦截器也支持用Interceptors.protype.eject方法移除。
(4)axios的取消请求功能是怎么实现的?
config配置cancelToken
在promise链式调用的dispatchRequest抛出错误
在adapter中request.abort()取消请求
使promise走向rejected
用户捕获错误信息
(5)源码压缩包
概念题
cookie、SessionStorage和localStorage的区别
共同点:
不同点:
1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。 cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。
2.存储大小限制也不同,cookie数据不能超过4K,sessionStorage和localStorage可以达到5M
3.sessionStorage:仅在当前浏览器窗口关闭之前有效;
localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;
cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
4.作用域不同 sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;
localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在
cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在
get和post两种基本请求方法的区别
GET和POST是什么?HTTP协议中的两种发送请求的方法。
HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
DOM
概念
DOM —> Document Object Model 文档对象模型
DOM 是一个对象 ----> 宿主对象
通过浏览器提供的这一套方法表示或者操作HTML和XML
Javascript
有三种的对象
本地对象和内置对象都是ECMAScript提供的
本地对象和内置对象都是ES的内部对象
本地对象:Native Object
Object、Function、Array、
String、Number、Boolean(包装类)
Error、EvalError、SyntaxError、RangeError、ReferenceError、TypeError、URIError、Date、RegExp
内置对象:Built-in Object
Global Math 这两种
ECMA - > isNAN ( ) parseInt ( ) Number decodeURI encodeURI
Infinity NAN undefined
宿主对象:Host Object
执行JS脚本的环境提供的对象(即浏览器提供的对象,所以又称为浏览器对象)
浏览器对象分为window(BOM)和document(DOM)
BOM > DOM (BOM 包含 DOM)
Document
document = {
}
getElementById
getElementsByTagName
< body>
< div> 123123div >
< div> 234234div >
< script>
var box = document. getElementsByTagName ( 'div' ) [ 0 ] ;
console. log ( box) ;
script >
body >
getElementsByClassName
< body>
< div class = " box" > 123123div >
< div class = " box" > 234234div >
< script>
var box = document. getElementsByClassName ( 'box' ) ;
console. log ( box) ;
script >
body >
getElementsByName
< body>
< input type = " text" name = " username" />
< script>
var input = document. getElementsByName ( 'username' ) ;
console. log ( input) ;
script >
body >
querySelector
HTML5 新引入WEB的API
querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。
只能选择一个,如果有重复,只选第一个
文档对象模型Document
引用的**querySelector()**
方法返回文档中与指定选择器或选择器组匹配的第一个 HTMLElement
对象。 如果找不到匹配项,则返回null
。
< body>
< div class = " text" > 123div >
< div> 234div >
< script>
var div1 = document. querySelector ( 'div' ) ;
var div2 = document. querySelector ( '.text' ) ;
console. log ( div1) ;
console. log ( div2) ;
script >
body >
根据css中的选择器来选择需要的
< body>
< div>
< h2>
< p> 123p >
h2 >
div >
< div>
< p> 234p >
div >
< script>
var p1 = document. querySelector ( 'div p' ) ;
var p2 = document. querySelector ( 'div > p' ) ;
console. log ( p1) ;
console. log ( p2) ;
script >
body >
querySelectorAll
选一组
querySelectorAll() 方法返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象。
NodeList 对象表示节点的集合。可以通过索引访问,索引值从 0 开始。
< body>
< div class = " box" > 123div >
< div class = " box" > 234div >
< div class = " box" > 345div >
< script>
var divs1 = document. querySelectorAll ( 'div' ) ;
var divs2 = document. querySelectorAll ( '.box' ) ;
var divs3 = document. querySelectorAll ( '.box' ) [ 1 ] ;
console. log ( divs1) ;
console. log ( divs2) ;
console. log ( divs3) ;
script >
body >
遍历节点树
parentNode
parentNode 属性作为Node 对象返回指定节点的父节点
< body>
< ul>
< li>
< h2> 我是h2标签h2 >
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
li >
ul >
< script>
var a = document. getElementsByTagName ( 'a' ) [ 0 ] ;
script >
body >
childNodes
返回节点的子节点集合,以 NodeList 对象。
可以使用 length 属性来确定子节点的数量,然后您就能够遍历所有的子节点并提取您需要的信息。
有哪些节点
元素节点 =1
属性节点 =2
文本节点 =3 (text)
注释节点 =8 (comment)
document =9
DocumentFragment =11
< body>
< ul>
< li>
< h2> 我是h2标签h2 >
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
li >
ul >
< script>
var li = document. getElementsByTagName ( 'li' ) [ 0 ] ;
console. log ( li. childNodes) ;
script >
body >
firstChild、lastChild
firstChild ---->获取目标元素节点下的所有子元素中的第一个子元素
目标元素节点.childNodes[0] = 目标元素节点.firstChild;
lastChild ---->获取目标元素节点下的所有子元素中的最后一个子元素
目标元素节点. childNodes[ 目标元素节点. childNodes. length- 1 ] = 目标元素节点. lastChild;
注意:firstChild和lastChild只能对单个节点就行操作,不能对节点数组进行操作;
< body>
< ul>
< li> 123
< h2> 我是h2标签h2 >
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
234li >
ul >
< script>
var li = document. getElementsByTagName ( 'li' ) [ 0 ] ;
console. log ( li. firstChild) ;
console. log ( li. lastChild) ;
script >
body >
nodeValue
< body>
< p id = " description" >
hello world!
p >
< script type = " text/javascript" >
var p = document. getElementById ( "description" ) ;
console. log ( p. childNodes[ 0 ] . nodeValue) ;
script >
body >
nextSibling
兄弟节点
获取下一个同胞元素,如果下一个同级节点不存在,则此属性返回值是null
该属性表示当前节点的下一个节点(其后的节点与当前节点同属一个级别);如果其后没有与其同级的节点,则返回null。
previousSibling
兄弟节点
该属性与nextSibling属性的作用正好相反
获取上一个同胞元素
< body>
< ul>
< li>
< a href = " #" > 我是a标签a > 123
< p> 我是p标签p > 345
< h2> 我是h2标签h2 >
li >
ul >
< script>
var p = document. getElementsByTagName ( 'p' ) [ 0 ] ;
console. log ( p. previousSibling) ;
console. log ( p. nextSibling) ;
script >
body >
遍历元素节点树
prarentElement
parentElement属性返回指定元素的父元素。
parentElement和parentNode之间的区别在于,如果父节点不是元素节点,则 parentElement返回null
IE9及以下不支持
< body>
< ul>
< li>
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
< h2> 我是h2标签h2 >
li >
ul >
< script>
var li = document. getElementsByTagName ( 'li' ) [ 0 ] ;
script >
body >
children
注意 :childElementCount = children.length
firstElementChild、lastElementChild
firstElementChild
属性返回指定元素的第一个子元素。
此属性与firstChild
之间的区别在于
firstChild
将第一个子节点作为元素节点,文本节点或注释节点(取决于哪个是第一个)返回,而firstElementChild
将第一个子节点作为元素节点返回(忽略文本)和注释节点)
children[0]first = ElementChild相同的结果
nextElementSibiling、previousElementSibling
< body>
< ul>
< li>
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
< h2> 我是h2标签h2 >
li >
ul >
< script>
var p = document. getElementsByTagName ( 'p' ) [ 0 ] ;
script >
body >
节点属性
节点
元素节点 =1
属性节点 =2
文本节点 =3 (text)
注释节点 =8 (comment)
document =9
DocumentFragment =11
nodeName
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
script >
body >
nodeValue
元素节点没有nodeValue
可以修改的,属性、注释、文本可用
获取属性节点
nodeType
封装一个打印节点数的函数(寻找子元素集合的方法)
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
function elemChildren ( node ) {
var arr = [ ] ,
children = node. childNodes;
for ( var i = 0 ; i < children. length; i++ ) {
var childItem = children[ i] ;
if ( childItem. nodeType === 1 ) {
arr. push ( childItem) ;
}
}
return arr;
}
console. log ( elemChildren ( div) ) ;
script >
body >
类数组
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
var arr = [ 1 , 2 , 3 ] ;
var obj = {
'0' : 1 ,
'1' : 2 ,
'2' : 3 ,
'length' : 3 ,
'push' : Array . prototype. push,
'splice' : Array . prototype. splice
}
obj. push ( 4 ) ;
script >
body >
DOM结构
DOM对象方法
节点操作
JS中的节点操作 写几个常用的API, 来操作DOM节点。 (1)document.getElementById()这个是最基本的了。 (2)object.innerHTML该属性设置或返回object之间的HTML (3)document.createElement()创建节点对象。 (4)document.body.appendChild()尾部插入结点。 (5)object.parentNode.removeChild(oChildNode);移除结点
DOM结构树
只有Document.prototype
有getElementById()
例子:
*
通配符
只有getElementsByTagName 能用
显示在body里的所有的标签名
var all = document. getElementsByTagName ( '*' ) ;
拿到body、head
例子
HTMLDocument . prototype - > body head
Document . prototype - > documentElement - > HTML
var p = document.getElementById(“description”); console.log(p.childNodes[0].nodeValue);
```
nextSibling
兄弟节点
获取下一个同胞元素,如果下一个同级节点不存在,则此属性返回值是null
该属性表示当前节点的下一个节点(其后的节点与当前节点同属一个级别);如果其后没有与其同级的节点,则返回null。
previousSibling
兄弟节点
该属性与nextSibling属性的作用正好相反
获取上一个同胞元素
< body>
< ul>
< li>
< a href = " #" > 我是a标签a > 123
< p> 我是p标签p > 345
< h2> 我是h2标签h2 >
li >
ul >
< script>
var p = document. getElementsByTagName ( 'p' ) [ 0 ] ;
console. log ( p. previousSibling) ;
console. log ( p. nextSibling) ;
script >
body >
遍历元素节点树
prarentElement
parentElement属性返回指定元素的父元素。
parentElement和parentNode之间的区别在于,如果父节点不是元素节点,则 parentElement返回null
IE9及以下不支持
< body>
< ul>
< li>
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
< h2> 我是h2标签h2 >
li >
ul >
< script>
var li = document. getElementsByTagName ( 'li' ) [ 0 ] ;
script >
body >
children
注意 :childElementCount = children.length
firstElementChild、lastElementChild
firstElementChild
属性返回指定元素的第一个子元素。
此属性与firstChild
之间的区别在于
firstChild
将第一个子节点作为元素节点,文本节点或注释节点(取决于哪个是第一个)返回,而firstElementChild
将第一个子节点作为元素节点返回(忽略文本)和注释节点)
children[0]first = ElementChild相同的结果
nextElementSibiling、previousElementSibling
< body>
< ul>
< li>
< a href = " #" > 我是a标签a >
< p> 我是p标签p >
< h2> 我是h2标签h2 >
li >
ul >
< script>
var p = document. getElementsByTagName ( 'p' ) [ 0 ] ;
script >
body >
节点属性
节点
元素节点 =1
属性节点 =2
文本节点 =3 (text)
注释节点 =8 (comment)
document =9
DocumentFragment =11
nodeName
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
script >
body >
nodeValue
元素节点没有nodeValue
可以修改的,属性、注释、文本可用
获取属性节点
nodeType
封装一个打印节点数的函数(寻找子元素集合的方法)
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
function elemChildren ( node ) {
var arr = [ ] ,
children = node. childNodes;
for ( var i = 0 ; i < children. length; i++ ) {
var childItem = children[ i] ;
if ( childItem. nodeType === 1 ) {
arr. push ( childItem) ;
}
}
return arr;
}
console. log ( elemChildren ( div) ) ;
script >
body >
[外链图片转存中…(img-7X4LjxdU-1630937429118)]
类数组
< body>
< div class = " box" id = " box" style = " background-color : green" >
我是文本节点
< h1> 我是标题标签h1 >
< a href = " #" > 我是超链接a >
< p> 我是段落标签p >
div >
< script type = " text/javascript" >
var div = document. getElementsByTagName ( 'div' ) [ 0 ] ;
var arr = [ 1 , 2 , 3 ] ;
var obj = {
'0' : 1 ,
'1' : 2 ,
'2' : 3 ,
'length' : 3 ,
'push' : Array . prototype. push,
'splice' : Array . prototype. splice
}
obj. push ( 4 ) ;
script >
body >
DOM结构
DOM对象方法
节点操作
JS中的节点操作 写几个常用的API, 来操作DOM节点。 (1)document.getElementById()这个是最基本的了。 (2)object.innerHTML该属性设置或返回object之间的HTML (3)document.createElement()创建节点对象。 (4)document.body.appendChild()尾部插入结点。 (5)object.parentNode.removeChild(oChildNode);移除结点
DOM结构树
只有Document.prototype
有getElementById()
例子:
*
通配符
只有getElementsByTagName 能用
显示在body里的所有的标签名
var all = document. getElementsByTagName ( '*' ) ;
拿到body、head
例子
HTMLDocument . prototype - > body head
Document . prototype - > documentElement - > HTML
注:此乃黄敢敢夜观各大网站视频所学即得笔记,如有雷同,请联系我进行删除!阿里嘎多 又注:还没写完笔记哟,同步更新