JavaScript学习 Day2 ~ Day3
1、严格检查模式
在js中可以像Python一样直接设置变量,但是这是全局变量,如果有多个js文件变量名称一样就会出问题
i = 1;
所以就有了这个严格检查模式 ‘use strict’;
// 严格检查模式,前提IDEA支持ES6
// 必须写在第一行
'use strict';
// 用var定义的变量是局部变量
//var i = 1;
// 但在ES6中,一般用let定义
let i = 1;
2、数据类型
2.1字符串
1.正常字符串我们使用 单引号或双引号包裹
2.转义字符和C语言java一样
\'
\n
\t
\u4e2d // \u#### Unicode字符
\x41 // ASCII
3.多行字符串 (使用tab键上面像顿号的符号引起来)
var a =`haha
xixi
wuwu`;
4.模版字符串
let b = "xiaoming";
let a = `你好呀,${b}`; // 必须用``号引起来
console.log(a);
5.字符串长度
console.log(b.length) //xiaoming
8
6.字符串可变性,不可变
console.log(b[0])
x
b[0] = 'a'
'a'
console.log(b[0])
x
7.大小写转换
// 注意这里是方法不是属性
console.log(b.toUpperCase())
XIAOMING
console.log(b.toLowerCase())
xiaoming
8.str.indexOf() 找下标
9.substring ()截取字符串
// 只截取到7前面那个字符 [)
console.log(b.substring(0,7))
xiaomin
2.2数组
Array可以包含任意的数据类型
var arr =[1,2,3,4,5,6];
1.长度
a.length
arr.length = 10 // 长度可以更改
10
arr
(10) [1, 2, 3, 4, 5, 6, empty × 4]
arr[8]
undefined
给 arr.length 赋值改变长度,变短会丢失数据
2.indexOf(),下标索引
var arr = [1,2,3,"1","2"]
arr.indexOf(1)
0
arr.indexOf("1")
3
字符"1"和数字1不一样
3.slice(),截取数组的一部分,类似String中的substring
arr.slice(2,4)
(2) [3, '1']
4.push(),pop()
arr.push("a","b")
7
arr
(7) [1, 2, 3, '1', '2', 'a', 'b'] // 在队尾添加数据
arr.pop()
'b'
arr.pop()
'a'
arr
(5) [1, 2, 3, '1', '2'] // 尾部删除
5.unshift(),shift()头部的添加删除,和上面一样
6.排序 sort(),元素反转reverse()
arr =["B","C","A"]
(3) ['B', 'C', 'A']
arr.sort()
(3) ['A', 'B', 'C']
arr.reverse()
(3) ['C', 'B', 'A']
7.拼接concat()
arr.concat([1,2,3])
(6) ['C', 'B', 'A', 1, 2, 3]
arr
(3) ['C', 'B', 'A']
注意:concat() 没有修改数组,只是会返回一个新的数组
8.连接符arr.join()
打印拼接数组,使用特定的字符串连接
arr.join(">")
'C>B>A'
9.多维数组
arr = [[1,2],[3,4]]
arr[0][1]
2
2.3 对象
var 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值,
...
}
// 调用
对象名.属性名
js中对象,{…}表示一个对象,键值对描述属性xxxx:xxxx,多个属性之间使用逗号隔开,最后一个属性不加逗号!
js中的所用的键都是字符串
1.对象赋值
a.b = c
2.使用一个不存在的对象属性,不会报错undefined!
a.ha
undefined
3.动态的删减属性
true
a
{name: 'xiaoming', tag: Array(2)}
4.动态的添加
a.haha = "haha"
'haha'
a
{name: 'xiaoming', tag: Array(2), haha: 'haha'}
5.判断属性值是否在这个对象中 xxx in xxx
"haha" in a
true
// 继承父类
"toString" in a
true
6.判断属性值是否在这个对象自身拥有的 hasOwnProperty()
a.hasOwnProperty("toString")
false
a.hasOwnProperty("haha")
true
2.4 流程控制
if - else if - else
…
while do{}while
…
forEach 循环 ES5.1
var a =[1,22,13,124,3544,5,435,356]
//函数
a.forEach(function (b){ // 数组里的数存储在b里
console.log(b)
})
for (xxx in xxx)
for (var b in a){ // b存储的是a的索引
console.log(a[b])
}
2.5 Map 和 Set
ES6的新特性
Map:
// 真 字典
var map = new Map([['小明',100],["小红",90],["小刚",50]]);
var name = map.get("小明"); // 通过key获得value
console.log(name);
// set(key) 添加 delete(key) 删除
map.set("哈哈",123);
Map(4) {'小明' => 100, '小红' => 90, '小刚' => 50, '哈哈' => 123}
map.delete("小明")
true
map
Map(3) {'小红' => 90, '小刚' => 50, '哈哈' => 123}
Set: 无序不重复集合
// 真 集合
var set = new Set([1,1,2,2,4,4,3,3]);
Set(4) {1, 2, 4, 3}
// add() 添加 delete() 删除
set.add(100)
Set(5) {1, 2, 4, 3, 100}
set.delete(1)
true
set
Set(4) {2, 4, 3, 100}
set.has(3) // has()是否包含括号里的值
true
2.5 iterator 作业
作业:使用 iterator 来遍历迭代 Map,Set
// 遍历Map
let map = new Map([
["小明",100],
["小红",60],
["小刚",0]
]);
let iter = map.entries();
let aa = iter.next();
while (!aa.done) {
console.log(aa.value[0]+":"+aa.value[1]);
aa = iter.next();
}
小明:100
小红:60
小刚:0
// 遍历Set
let set = [1,2,3,0,9,8];
let iter = set.entries();
let aa = iter.next();
while (!aa.done) {
console.log(aa.value[1]);
aa = iter.next();
}
iterator 可以说是个接口
只要配置了iterator接口就可以遍历,变成可迭代对象?
for - of
ES6 创造了 for ( xx of xx) 循环给iterator用
和for…in 不一样的地方是
for in 返回的是下标,不能遍历Map for of 是一整个块
let map = new Map([["小明",100],["小红",60],["小刚",0]]);
let aa =[[1,2],[3,4]]
for (let i in map){console.log(i);} // 不显示
for (let i of map){console.log(i);}
(2) ['小明', 100]
(2) ['小红', 60]
(2) ['小刚', 0]
for (let i in aa){console.log(i);}
0
1
for (let i of aa){console.log(i);}
(2) [1, 2]
(2) [3, 4]
iterator 有自己的方法 Symbol.iterator
!!!但是只适用于数组、字符串,对Map和Set 没用
数组使用:
let a = [1,2,3,5,6,7,8];
let b = a[Symbol.iterator]();
/*
console.log(b.next());
{value: 1, done: false} 显示出来两个
所以next出来的就可以去 .value .done
但是b本身只是迭代器对象 它不能去 .
但但是next每次使用就会"next"
不能同时把value 和 done 拿出来
所以需要一个变量来接住这个next
*/
let c = b.next();
while (!c.done){ // done有的话是false
console.log(c.value);
c =b.next();
}
这时候变量就可以使用它的方法
.next() 第一次用去第一个值,之后用去下一个值
返回两个 {value: , done: } 这个才可以 . 不可以直接用变量 .
!!!done 没有下一个是true
.return() 结束并返回一个值 .value .done
.throw() 报错
Map 和 Set 使用:
// 有三种方法生成这个迭代器
let iter = set.entries(); // 数组为值
let keys = set.keys(); // key为值
let values = set.values(); // 值为值
// 这的next同样返回一{value,done} 就是value返回的类型不一样
// 遍历的话也是一样的,Set也是这样
console.log(iter.next());
/*
{value: Array(2), done: false}
done: false
value: Array(2)
0: "小明"
1: 100
length: 2
*/
console.log(keys.next());
/*
{value: '小明', done: false}
done: false
value: "小明"
*/
console.log(values.next());
/*
{value: 100, done: false}
done:false
value:100
*/
3、函数
3.1 定义一个函数
定义方式一
function 函数名(){ // 不用写返回值类型
......
// return ...
}
如果没有执行return,函数执行完也会返回结果,结果就是 undefined or NaN
定义方式二
var 函数名 = function(){
//↑成函数了
}
function(){…} 是一个匿名函数。但是可以把结果赋值给变量
调用函数
函数名(参数);
参数问题:js可以传任意个参数也可以不传递参数
参数进来是否存在的问题?假设不存在如何规避?
if (typeof a !== "数据类型") { // js 的不等于是 "!==""
throw "报错语句";
}
ha()
Uncaught Not a number! // 手动抛出异常
arguments
代表,传递进来的所有参数,是一个数组
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]); // 打印所有参数
}
有时候会想用多余的参数进行附加操作,需要排除已有的参数
rest
以前:
if (arguments.length > 1){
for (i = 1; i < arguments.length; i++){
....
}
}
ES6引入新的特性,获取除了已经定义的其他参数
function ha(a,b,...rest){ // rest 也是个数组
console.log(rest);
}
ha(1,2,3,4,5,6)
(4) [3, 4, 5, 6]
3.2 变量的作用域
常见的作用域,和其他语言没啥变化
值得记的点:
提升变量的作用域
var a = "a" + b;
console.log(a);
var b = "b"; // 把变量的定义写在下面,没写就报错了
aundefined // b 是"undefined"
js执行引擎,自动提升了变量的定义,但没赋值
养成规范:所有定义都放在头部
全局变量
// 不在任何一个{}里
i = 1; // 可以跨文件
var/let q = 1; // 跨不了
全局对象 window
var a = "sdasd"
alert(a);
alert(window.a); // 完全一致
因为alert()本身就是window的一个变量(赋值了函数)
let a = "aaa";
// alert() 其实数属于window 的一个变量
window.alert(a);
// 可以赋值给别的函数
let c = window.alert;
c("c");
// 可以重写
window.alert = function (){}
alert(a);
// 恢复
alert = c;
alert("aaaaa");
找不到的变量报错:ReferenceError
规范
1.设置唯一全局变量,把自己的代码放在自己唯一的空间中,减低全局变量名冲突的问题 jQuery
var a = {};
// 想加全局变量的时候
a.name = "xiaoming";
a.add = function(a,b){
return a + b;
}
2.局部作用域 let
for (var i = 0; i < 100; i++) {}
console.log(i + 1); // var 不是局部的!!!
局部得用 let,ES6
3.常量关键字 const
在ES6前,定义常量只能全凭自觉,全部字母大写,想改还是能改
const AA = "AA";
// AA = 1; 改的话就会报错