前端基础之JavaScript

前端基础之JavaScript

JavaScript和Java没有半毛钱关系,由于当时的Java热度很热,蹭一下热度。

1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这门语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。

该标准一开始就是针对JavaScript语言制定的,但是没有称其为JavaScript,有两个方面的原因。一是商标,JavaScript本身已被Netscape注册为商标。而是想体现这门语言的制定者是ECMA,而不是Netscape,这样有利于保证这门语言的开发性和中立性。
因此ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。

ECMAScript的常用版本

年份 名称 简称 描述
2011 ECMAScript 5.1 es5 添加"strict mode"严格模式
添加JSON支持
2015 ECMAScript 6 es6 添加类和模块

尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。

组成部分

一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:

  • 核心(ECMAScript)
  • 文档对象模型(DOM) Document object model (整合js,css,html)
  • 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)。eg:浏览器大小、滑动、弹出新浏览器窗口

简单地说,ECMAScript 描述了JavaScript语言本身的相关内容。

  • JavaScript 是脚本语言
  • JavaScript 是一种轻量级的编程语言。
  • JavaScript 是可插入 HTML 页面的编程代码。
  • JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
  • JavaScript 很容易学习。

JavaScript书写与引入

书写位置

  1. 直接开设js文件写
  2. 在html文档中的script标签内书写
    可以在body标签中写。这样代码会先加载标签,后加载js。
  3. 在浏览器的控制台中也可以写
    右击检查--> Console中

在用浏览器书写js的时候,左上方的清空按钮只是清空当前页面,代码其实还在。如果你想要重新书写,最好重新开设一个页面。
在使用浏览器书写你自己的js代码时,推荐你重新打开你的html页面使用cunsole,因为其他页面会有限制。

引入方式

  1. script标签中书写
<script>
  // 在这里写你的JS代码
</script>
  1. script中的src属性,引入外部js文件
<script src="myscript.js"></script>

JavaScript语言

注释

// # 单行注释

/*
	多行注释
    多行注释
    多行注释
*/

结束符

js的每一行代码都是使用;结尾。但是要注意:;不是必须写的,但是推荐写上。

变量声明

声明变量的两种方式:

1.es5的语法

var name = "tank";
var age = 20;

2.es6的语法

let name='kevin';
let age = 22;

注意:
1.我们在写js代码的时候,都选择es6版本,因为es6兼容es5
2.pycharm中怎么选择es6版本:settings --> Languangs --> JavaScript

区别:
var在for循环中定义的也会影响到全局
let在局部中定义的也只会在局部生效

变量名的命名规范:

  1. 变量名可以使用下划线,数字,字母,$组成,不能以数字开头。
  2. 变量名是区分大小写的。
  3. 保留字不能用做变量名。

补充的保留字

abstract
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile

常量

python中没有真正的常量,默认全大写就是常量。
js中有真正的常量。并且,在js中定义常量,常量定义好后就不能更改了。

js中用const来声明常量

const PI = 3.1415926  // undefined
PI  // 3.1415926

更改PI的值会报错
PI = 3
// VM415:1 Uncaught TypeError: Assignment to constant variable.
//  at <anonymous>:1:4

查看变量

console.log(变量名)

JavaScript数据类型

js是一门拥有动态类型的语言,python语言也是

var x;  // 此时x是undefined
var x = 1;  // 此时x是数字
var x = "Tony"  // 此时x是字符串

x可以指向任意的数据类型,有些编程语言中,变量名指向一种后,后续就只能指向同一种数据类型,不能够更改。

数值型(Number)

js中不区分整型和浮点型,统称为数值类型(Number)

数值类型:

  1. 整型
  2. 浮点型
  3. NaN,不是一个数字(not a number)

查看变量的数据类型

typeof 123;  // "number"
typeof 11.44;  // "number"
typeof NaN;    // "number"

类型转换

console.log(parseInt('123'), typeof(parseInt('123')));  // 123 'number'
console.log(parseFloat('11.33'), typeof(parseFloat('11.33')));  // 11.33 'number'

console.log(parseInt('ABC'), typeof(parseInt('ABC')));  // NaN 'number'
console.log(parseFloat('abc'), typeof(parseFloat('abc')));  // NaN 'number'
// 返回NaN,NaN属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。

console.log(parseFloat('111abc'), typeof(parseFloat('111abc')));  // 111 'number'
console.log(parseFloat('ghjii123abc'), typeof(parseFloat('ghjii123abc')));  // NaN 'number'

/*
1.必须以数字开头。数字开头之只转数字,遇到不是数字的,就返回,把之前的数字输出。
2.字母开头就直接返回NaN
*/ 

字符串(string)

1.定义字符串

var str = 'kevin';
var str = "kevin";
// var str = '''kevin''';  # 三引号不行

2.模板语法:(es6的语法)
1.可以定义多行文本

var s3 = `
gajlgja
nkgkla
maljhji;
`
typeof s3;
// "string"

2.可以实现格式化字符串操作
书写${}会自动去前面找大括号里面的变量名对应的值,如果没有定义会直接报错

let name = 'jack';
let age = 20;
let str = `my name is ${name}, my age is ${age}`;  // 只能写存在的变量名
console.log(str)  
// my name is jack, my age is 20

3.字符串拼接
js中推荐直接使用+拼接字符串,python中可以使用+和join来拼接字符串

let name = 'hello';
let bb = 'word';
console.log(name + bb);  // helloword
console.log(name + 1);  // hello1 // 可以字母跟数字拼接
console.log(name + 111);  // hello111

4.常用内置方法
js也是一门基于面向对象的语言,即一切皆对象!!!。可以使用对象点属性,对象点方法。

方法 说明 python中的方法
.length 返回长度 len(str)
.trim() 移除空白 str.strip()
.trimLeft() 移除左边的空白 str.lstrip()
.trimRight() 移除右边的空白 str.rstrip()
.charAt(n) 返回第n个字符 str[index]
.concat(value, ...) 拼接 '%'.join(str)
.indexOf(substring, start) 子序列位置 str.find('str1')
str.index('str1')
.substring(from, to) 根据索引获取子序列
.slice(start, end) 切片 str[0:9:2]
.toLowerCase() 小写 str.lower()
.toUpperCase() 大写 str.upper()
.split(delimiter, limit) 分割 str4.split('.',切割次数)

具体使用:

// 记忆的时候一定要对比python去记忆

var name = '   hello   '
undefined
console.log(name)  // 输出变量,相当于python的print
hello   
typeof(name)  // 查看数据类型
'string'

name.length  // 返回长度,没有括号,对象调属性
11

name.trim()
'hello'
name.trimLeft()
'hello   '
name.trimRight()
'   hello'
var name2 ='%%jason%%'
undefined
name2.trim('%')  // 不能去除特殊的字符
'%%jason%%'

name2.charAt(0)
'%'
name2.charAt(4)
's'
name2.indexOf('ja')  // 返回子字符串在母字符串的索引位置	
2
name2.indexOf('hhh')  // 没有则返回-1
-1

name2.substring(0,5)
'%%jas'
name2.substring(0,-1)  // 不能识别负数
''
name2.slice(0,5)
'%%jas'
name2.slice(0,-1)  // 可以识别负数,后面推荐使用slice就行
'%%jason%'

var name3 = 'cGoNGH234447HahA'
undefined
name3.toLowerCase()  // 小写
'cgongh234447haha'
name3.toUpperCase()  // 大写
'CGONGH234447HAHA'


var name = 'tank|jason|mengd|lgdi|899|...'
undefined
name.split('|')
(6) ['tank', 'jason', 'mengd', 'lgdi', '899', '...']
name.split('|',2)  // 第二个参数是获取分割后的元素个数,python中是限制切割字符的个数
(2) ['tank', 'jason']0: "tank"1: "jason"length: 2[[Prototype]]: Array(0)
name.split('|',10)  
(6) ['tank', 'jason', 'mengd', 'lgdi', '899', '...']

// concat(value,...) 拼接 
联想记忆:
	MySQL中,concat、cancat_ws、group_concat
	python中,join

name.concat(name2)
'tank|jason|mengd|lgdi|899|...%%jason%%'
var p = 111
undefined
name.concat(p)  // js是弱类型(内部会自动转换成相同的数据类型做操作)
'tank|jason|mengd|lgdi|899|...111'  // 把数字111拼接了,最后结果是字符串

slice和substring的区别

string.slice(start, stop)和string.substring(start, stop):


两者的相同点:
如果start等于end,返回空字符串
如果stop参数省略,则取到字符串末
如果某个参数超过string的长度,这个参数会被替换为string的长度

substirng()的特点:
如果 start > stop ,start和stop将被交换
如果参数是负数或者不是数字,将会被0替换

silce()的特点:
如果 start > stop 不会交换两者
如果start小于0,则切割从字符串末尾往前数的第abs(start)个的字符开始(包括该位置的字符)
如果stop小于0,则切割在从字符串末尾往前数的第abs(stop)个字符结束(不包含该位置字符)

布尔值(Boolean)

python中的布尔值是首字母大写

True
False

js中的布尔值是全小写

true
false

在js中有哪些是假的?0 空字符串 NaN null undefined都是false

null和undefined的区别

  • null,表示值是空,一般在需要指定或清空一个变量时才会使用,如 name=null;
  • undefined,表示当声明一个变量但未初始化时,该变量的默认值是undefined。还有就是函数无明确的返回值时,返回的也是undefined。

直接看图吧!

对象(Object)

JavaScript 中的所有事物都是对象:字符串、数值、数组、函数...此外,JavaScript 允许自定义对象。
JavaScript 提供多个内建对象,比如 String、Date、Array 等等。
对象只是带有属性和方法的特殊数据类型。

  • 数组(类似于python里面的列表) [ ]
  • 自定义对象(类似于python里面的字典)

数组

数组对象的作用是:使用单独的变量名来存储一系列的值。类似于Python中的列表。

var l = [1, 2, 3, 4];  // 一维数组
var ll = [1, 2, [3, 4,[5, 6]]];  // 三维数组

var lll = [1, 11.4, 'a', [3, 4]];  // 数组中可以存放任意的数据类型

// 查看数据类型
typeof l;
"object"

// 支持索引取值,索引从0开始
console.log(l[0]);  // 1

// 遍历数组中的元素
var a = [10, 20, 30, 40];
for (var i=0;i<a.length;i++) {
  console.log(i);
}

数组的内置方法

方法 说明 python中的方法
.length 数组的大小 len(lst)
.push(ele) 尾部追加元素 lst.append(ele)
lst.insert(index,ele)
.pop() 获取尾部的元素 lst.pop()
.unshift(ele) 头部插入元素 lst.insert(0,ele)
.shift() 头部移除元素 lst.pop(0)
.slice(start, end) 切片 lst[0:9:2]
.reverse() 反转 lst.reverse()
lst[::-1]
.join(seq) 将数组元素连接成字符串 str(lst)
.concat(val, ...) 连接数组 lst.extend(lst2)
.sort() 排序 lst.sort()
.forEach() 将数组的每个元素传递给回调函数
.splice() 删除元素,并向数组添加新元素。
.map() 返回一个数组元素调用函数处理后的值的新数组

具体使用:

var l = [111,222,333,444,555,666]
undefined

l.length;
6

l.push(999)
7
l
(7) [111, 222, 333, 444, 555, 666, 999]

l.pop()
999
l
(6) [111, 222, 333, 444, 555, 666]

l.unshift(964)
7
l
(7) [964, 111, 222, 333, 444, 555, 666]

l.shift()
964
l
(6) [111, 222, 333, 444, 555, 666]

l.slice(1,4)
(3) [222, 333, 444]

l.reverse()
(6) [666, 555, 444, 333, 222, 111]

l.join('&')  // 跟python中刚好相反,'字符'.join(str)
'666&555&444&333&222&111'

l.concat([33,44,55])  // python中extend扩展列表
(9) [666, 555, 444, 333, 222, 111, 33, 44, 55]

l.sort()
(6) [111, 222, 333, 444, 555, 666]

python中的使用

# 1.join
print('$'.join('hello'))  # h$e$l$l$o

l = [1, 2, 3, 4, 5, 6, 7]
res = '|'.join(l)  # 直接报错,python中的join只能给字符串拼接,不能给列表拼接
# print(l) 

# 2.列表增加
l = [11, 22, 33, 44, 55]
# 2.1 append()尾部追加元素
l.append(777)
print(l)  # [11, 22, 33, 44, 55, 777]
# 2.2 insert,增加指定位置的元素
l.insert(3, 0)
print(l)  # [11, 22, 33, 0, 44, 55, 777]
# 2.3 extend,扩展列表(内部for循环+append)
l.extend([333, 777, 888])
print(l)  # [11, 22, 33, 0, 44, 55, 777, 333, 777, 888]

# 3.删除
# 3.1 pop(),弹出元素
l.pop()
print(l)  # [11, 22, 33, 0, 44, 55, 777, 333, 777]
a = l.pop(4)
print(a)  # 44
print(l)  # [11, 22, 33, 0, 55, 777, 333, 777]
# 3.2 remove(值)
l.remove(333)
print(l)  # [11, 22, 33, 0, 55, 777, 777]
# 3.3 del 列表[index]
del l[3]
print(l)  # [11, 22, 33, 55, 777, 777]

# 4.map(),映射
ll = [1, 2, 3, 4, 5]
res1 = map(lambda x: x ** 2, ll)
print(list(res1))  # [1, 4, 9, 16, 25]

# 5.zip(),拉链
l1 = [111, 222, 333, 444, 555]
l2 = ['kevin', 'jason', 'tank']
res2 = zip(l1, l2)
print(list(res2))  # [(111, 'kevin'), (222, 'jason'), (333, 'tank')]

# 6.filter,过滤
res3 = filter(lambda x: x > 300, l1)
print(list(res3))  # [333, 444, 555]

# 7.reduse,多个进一个出
from functools import reduce
lll = [1, 2, 3, 4, 5, 6]
res4 = reduce(lambda x, y: x + y, lll)
print(res4)  # 21
res5 = reduce(lambda x, y: x + y, lll, 100)
print(res5)  # 121

3个重要的方法

forEach的用法
语法:
forEach(function(currentValue, index, arr), thisValue)

参数:

参数 描述
function(currentValue, index, arr) 必需。 数组中每个元素需要调用的函数。
thisValue 可选。传递给函数的值一般用 "this" 值。
如果这个参数为空, "undefined" 会传递给 "this" 值。
函数参数:
参数 描述
currentValue 必需。当前元素
index 可选。当前元素的索引值。
arr 可选。当前元素所属的数组对象。

具体使用:

var ll = [111,222,333,444,555]
undefined
ll.forEach(function(value){console.log(value)})
/* 一个参数就是数组里面的每一个元素对象
111
222
333
444
555
*/

ll.forEach(function(value,index){console.log(value,index)})
/* 两个参数是元素+元素索引
111 0
222 1
333 2
444 3
555 4
*/

ll.forEach(function(value,index,arr){console.log(value,index,arr)})
/*  三个参数是元素+元素索引+元素的数据来源
111 0 (5) [111, 222, 333, 444, 555]
222 1 (5) [111, 222, 333, 444, 555]
333 2 (5) [111, 222, 333, 444, 555]
444 3 (5) [111, 222, 333, 444, 555]
555 4 (5) [111, 222, 333, 444, 555]
*/

ll.forEach(function(value,index,arr,four){console.log(value,index,arr,four)})  // 最多只有三个参数
/*
111 0 (5) [111, 222, 333, 444, 555] undefined
222 1 (5) [111, 222, 333, 444, 555] undefined
333 2 (5) [111, 222, 333, 444, 555] undefined
444 3 (5) [111, 222, 333, 444, 555] undefined
555 4 (5) [111, 222, 333, 444, 555] undefined
*/


splice()
语法:
splice(index,howmany,item1,.....,itemX)

参数:

参数 描述
index 必需。规定从何处添加/删除元素。
该参数是开始插入和(或)删除的数组元素的下标,必须是数字。
howmany 必需。规定应该删除多少元素。必须是数字,但可以是 "0"。
如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。
item1, ..., itemX 可选。要添加到数组的新元素。

具体使用:

ll.splice(0,3)  // 两个参数,第一个是起始位置,第二个是要删除的个数
(3) [111, 222, 333]
ll
(3) [444, 555, 666]
ll.splice(0,1,999)  // 三个参数是先删除后添加
[444]
ll
(3) [999, 555, 666]
ll.splice(0,1,[111,222,333,444])
[999]
ll
(3) [Array(4), 555, 666]  // 新添加的是数组,就显示一个组合array(个数)
0: (4) [111, 222, 333, 444]
1: 555
2: 666
length: 3
[[Prototype]]: Array(0)

map()
语法:
map(function(currentValue,index,arr), thisValue)

参数:

参数 描述
function(currentValue, index, arr) 必需。数组中的每个元素都会执行这个函数。
thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"
函数参数:
参数 描述
currentValue 必需。当前元素的值
index 可选。当前元素的索引值。
arr 可选。当前元素所属的数组对象。

具体使用:

// 用法跟forEach的用法一致
var ll = [11,22,33,44]
undefined
ll.map(function(value){return value+1})
(4) [12, 23, 34, 45]
ll.map(function(value,index){return value+1})
(4) [12, 23, 34, 45]
ll.map(function(value,index,arr){return value+1})
(4) [12, 23, 34, 45]

运算符

算数运算符

+ - * / % ++ --


// 有关于++(自增)的使用:
var i = 10;
var res1 = i++;
var res2 = ++i;
res1  
// 10
res2  
// 12

++d表示自增,类似于 i+=1
加号在前面是先加后赋值,加号在后面是先赋值后加

比较运算符

> >= < <= != == === !==

重点

1 == “1”  // true  弱等于,内部自动转换成相同的数据类型比较了
1 === "1"  // false 强等于,内部不做类型转换


// 1.上面这张情况出现的原因在于JS是一门弱类型语言(会自动转换数据类型),所以当你用两个等号进行比较时,JS内部会自动先将
// 2.数值类型的1转换成字符串类型的1再进行比较,所以我们以后写JS涉及到比较时尽量用三等号来强制限制类型,防止判断错误
// 3.比较运算符的应用:前后端数据交互,(前端是需要用户输入数据,一般是字符串,这时数据交互就可以使用弱等于)

逻辑运算符

js中 --------->  python中

&&     --------->   and
||     --------->   or
!      --------->   not

赋值运算符

= += -= *= /=

流程控制

if判断

语法:
if(条件){条件成立之后执行的代码块};

if语句

var age = 28;
if (age>18) {
    console.log('if条件成立执行的代码');
}

if-else语句

var age = 28;
if (age>18) {
    console.log('if条件成立执行的代码');
}else {
    console.log('条件不成立执行的代码');
}

if-else if-else语句

var age = 28;
if (age<18) {
    console.log('age<18,执行的代码');
}else if (age<24) {
    console.log('age大于18小于24,执行的代码块');
}else {
    console.log('条件都不成立执行的代码');
}
"""
在js代码中是没有缩进的,只不过我们处于python的书写习惯人为加上了而已
()条件
{}代码块
"""

switch语法

提前列举好可能出现的条件和解决方式,条件满足就执行对应的操作

var num = 2;
switch(num){
    case 0:
        console.log('Sunday');
        break;  // 不加break,匹配到一个后,就会一直往下执行
    case 1:
        console.log('Monday');
        break;
    case 2:
        console.log('Tuesday');
        break;
    case 3:
        console.log('Wednesday');
        break;
    default:
        console.log('条件都没有匹配上,默认走的流程');
}

// switch中的case子句通常都会加break语句,否则程序会继续执行后续case中的语句。

for循环

语法:
for (设置起始位;循环条件;i的变化){满足条件执行的代码块}

实际使用:

// 打印0-9数字
for (let i=0;i<10;i++){
    console.log(i);
}

// 题目:循环打印出数组中的每个元素
var ll = [111,222,333,444,555,666]
for (let i=0;i<ll.length;i++){
    console.log(ll[i]);
}

while循环

语法:
while(条件){
满足条件执行的代码块;
i的变化;
}

var i = 0;
while(i<5){
    console.log(i);
    i++;
}

三元运算符

python中的三元运算符:

# python
res = a if 条件 else b

js中的三元运算符:

# js
a > b ? a : b  // 条件成立取问号后面的值,不成立取冒号后面的值
var res = 2 > 5 ?8 :10  // 10
    

# 嵌套使用
var a=10,b=20;
var x=a>b ?a :(b=="20") ?a:b;  
x  
// 10

函数

函数定义

在python中定义函数需要用到关键字def。而在js中定义函数要用到关键字function。

语法格式:
function 函数名(形参1,形参1,形参1,...){函数体代码}

# 普通函数定义
function f1() {
	console.log("Hello world!");
}

# 调用函数:函数名加括号
f1();  // 调用:加括号调用,跟python一样


# 有参函数
function func2(a,b){
    console.log(a,b)
}

func2(1,2)
// 1 2
func2(1,2,3,4,5,6)  // 传参,传多了没有关系,只要对应的值
// 1 2
func2(1)  // 传少了也没有关系,b参数如果不传就是undefined
// 1 undefined


# 内置的arguments对象
 function sum(a, b) {
        console.log(arguments)  // 能够获取到函数接收的所有的参数,数组类型
     	console.log(a,b)
        console.log(arguments[4])
}

sum(1,2,3,4,5); // js函数中如果实参多传了,所有的参数都传给去了哪里?-->  arguments--> 数据类型-->  通过数据取值

# 给函数做限制
function func2(a,b){
    if (arguments.length<2) {
        console.log('传少了')
    }else if (arguments.length>2){
        console.log('传多了')
    }else{
        console.log('正常执行')
    }
}


# 函数的返回值
function index(){
    return 666
}

function index(){
    return 666,777,888,999
}
res=index();
999  // 返回值有多个,也只能拿到最后一个

# 想要拿多个返回值,只能是以数组形式返回
function index(){
    return [666,777,888,999]
}
res=index();
(4) [666, 777, 888, 999]


# js不支持解压赋值


# 匿名函数(了解)
function(){
    console.log('哈哈哈')
}

// 想要调用只能是先用一个变量名接收整个匿名函数,res是函数的内存地址。
var res = function(){
    console.log('哈哈哈')
}
res()  // 调用变量名加括号


#  立即执行函数(了解)
书写立即执行的函数,首先先写两个括号(函数)(参数)这样防止书写混乱,了解,但不要用这种方式书写。
(function(a, b){
  return a + b;
})(1, 2);


# 箭头函数(了解)
主要是用来处理简单的业务逻辑。类似于python中的匿名函数
var func3 = v => v;  // 箭头左边的是形参,右边的是返回值
// 等价于
var func3 = function(v){
    return v
}

var func4 = (arg1,arg2) => arg1+arg2
var func4 = function(arg1,arg2){
    return arg1+arg2
}

'''在js中,一般情况不会轻易报错,因为跟用户直接打交道的。'''

函数的全局变量和局部变量

局部变量:
在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。

全局变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。

作用域:
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。与python作用域关系查找一模一样!

几个例子:
1.

var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  

输出结果是?

// ShenZhen
var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;  // 函数名就是函数的内存地址
}
var ret = f();  // ret ====> Bar函数的内存地址
ret();  

输出结果是?

// BeiJing

3.闭包

var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret(); 

输出结果是?

// ShangHai

内置对象和方法

自定义对象

你可以看成是我们python中的字典,kv键值对的形式。但是js中的自定义对象要比python里面的字典操作更加方便

# 创建自定义对象 {}
var d={};  // 空对象
"""第一种创建自定义对象的方式"""


var obj = {'name':'kevin', 'age':20}; 
console.log(typeof obj);
console.log(obj)


# 取值
console.log(obj['name'])  //字典取值  // 不能使用get取值
console.log(obj.age)  // 对象.属性名 来取值


# 给对象增加值
obj['name'] = 'tank';  // key存在直接改值,如果不存在,就是增加值
obj.salary = 2000;  
console.log(obj)

# 删除
delete obj.name  // 关键字:delete
console.log(obj)


"""第二种创建自定义对象的方式 需要使用关键字new"""
// 2. 定义一个空对象出来
var obj1 = new Object();  // var obj1 = {};
console.log(obj1);

// 增加值
obj1.name = 'kevin';
obj1['age'] = 20;
console.log(obj1);

// 改
obj1.name1 = 'tank';
console.log(obj1);

// 删除
delete obj1.name1;
console.log(obj1);

Date对象

创建Date对象

# 在js中处理时间对象
let d3 = new Date()
Sun Apr 16 2023 16:29:56 GMT+0800 (GMT+08:00)
        
d3.toLocaleString()
'2023/4/16 16:29:56'

# 也可以自己手动输入时间
let d4 = new Date('2030/04/16 11:11:11') 
Tue Apr 16 2030 11:11:11 GMT+0800 (GMT+08:00)
d4.toLocaleString()
'2030/4/16 11:11:11'

let d5 = new Date(2021,4,4,11,11,11)
d5.toLocaleString()  // 月份是从0开始的(0-11月)
'2021/5/4 11:11:11'

Date对象的方法:

let d6 = new Date()

d6.getFullYear()  // 获取完整年份
d6.getYear ()  // 获取累计年(从1900年开始)
d6.getMonth()  // 获取月份(0-11)
d6.getDate()  // 获取日
d6.getDay()  // 获取星期
d6.getHours()  // 获取小时
d6.getMinutes()  // 获取分钟
d6.getSeconds()  // 获取秒
d6.getMilliseconds()  // 获取毫秒 
d6.getTime()  // 时间戳,返回累计毫秒数(从1970/1/1零点开始)

练习:

编写代码,将当前日期按“2017-12-27 11:11 星期三”格式输出。

const WEEKMAP = {
    0: "星期天",
    1: "星期一",
    2: "星期二",
    3: "星期三",
    4: "星期四",
    5: "星期五",
    6: "星期六"
};  //定义一个数字与星期的对应关系对象


function showTime() {
    var d1 = new Date();
    var year = d1.getFullYear();
    var month = d1.getMonth() + 1;  //注意月份是从0~11
    var day = d1.getDate();
    var hour = d1.getHours();// 02 03 04 05 15
    var minute = d1.getMinutes() < 10 ? "0" + d1.getMinutes() : d1.getMinutes();  //三元运算

    var week = WEEKMAP[d1.getDay()];  //星期是从0~6

    var strTime = `
${year}-${month}-${day} ${hour}:${minute} ${week}
`;
    console.log(strTime)
};

showTime();

详细Date对象方法:https://www.w3school.com.cn/jsref/jsref_obj_date.asp

JSON对象

# 在python中如何进行序列化和反序列化
import json
json.dumps()  # 序列化
json.loads()  # 反序列化

对于js来说,它也有相对于的序列化和反序列化

'''以下这两个方法务必掌握'''
JSON.stringify()  // 序列化
JSON.parse()   // 反序列化


let obj1 = {'name':'kevin','age':20}
let str2 = JSON.stringify(obj1)
'{"name":"kevin","age":20}'
JSON.parse(str2)
{name: 'kevin', age: 20}

RegExp对象

正则表达式在这里使与python中一摸一样。

在python中如果使用正则,要借助于re模块。在js中需要你自己创建正则对象。

# 在js中需要你自己创建正则对象
// 第一种
let reg1 = new RegExp('^[a-zA-Z][a-zA-Z0-9]{5,11}')
// 第二种
let reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/


# 正则校验数据
reg1.test('egondsb')  // true
reg2.test('egondsb')  // true


# 全局匹配
// 题目:获取字符串里面的所有字母s
let aaa = 'egondsb dsb dsb'
aaa.match(/s/)  // 拿到一个就停止了
aaa.match(/s/g)  // 全局匹配,g就表示全局模式

aaa.match(/s/)
//['s', index: 5, input: 'egondsb dsb dsb', groups: undefined]
aaa.match(/s/g) 
//(3) ['s', 's', 's']


# 区分大小写
// 默认是区分大小写的,如何不区分大小写呢?一样加标识符(g, i)  i: ignore
var bbb = 'egondsb dSb dsb';
bbb.match(/s/g)
// (2) ['s', 's']
bbb.match(/s/gi) 
//(3) ['s', 'S', 's']

全局匹配模式困扰点

# 困扰点1
let reg3 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/g
reg3.test('egondsb')

reg3.test('egondsb')  // 全局模式有一个lastIndex属性
true
reg3.test('egondsb')  // 返回false时,lastIndex属性值重置为0.
false
reg3.test('egondsb')  // 这时,比较成功lastIndex属性值为字符长度7,下一次比较就会从末尾开始,所以下一次的比较会是false。
true
reg3.test('egondsb')
false

reg3.lastIndex
0
reg3.test('egondsb')
true
reg3.lastIndex
7

## 困扰点2
let reg4 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/
reg4.test()

reg4.test()  // 什么都不传,默认传的是undefined,符合此时的正则语句,所以返回true
true
reg4.test()
true

验证:
reg5 = /undefined/
reg5.test()
true

"""
总结:你在用js书写正则的时候一定要注意上述问题
"""

扩展阅读:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

Math对象

abs(x)      返回数的绝对值。
exp(x)      返回 e 的指数。
floor(x)    对数进行下舍入。
log(x)      返回数的自然对数(底为e)。
max(x,y)    返回 x 和 y 中的最高值。
min(x,y)    返回 x 和 y 中的最低值。
pow(x,y)    返回 x 的 y 次幂。
random()    返回 0 ~ 1 之间的随机数。
round(x)    把数四舍五入为最接近的整数。
sin(x)      返回数的正弦。
sqrt(x)     返回数的平方根。
tan(x)      返回角的正切。

使用:

Math.abs(-10);
Math.max(1, 10);
Math.random();
posted @ 2023-04-19 15:32  星空看海  阅读(29)  评论(0编辑  收藏  举报