弹窗
alert() 方法用于显示带有一条指定消息和一个 确认 按钮的警告框。
function myFunction(){
alert("你好,我是一个警告框!");
}
confirm()方法用于显示一个带有指定消息和确认及取消按钮的对话框。
如果访问者点击"确定",此方法返回true,否则返回false。
var r=confirm("按下按钮!");
prompt()方法用于显示可提示用户进行输入的对话框。
var re = prompt("请输入你的银行卡 我要骗钱了")
console.log(re)
计时器
time() timeEnd可以计时从time到timeEnd之间代码的运行时间
console.time()
for (var i = 0; i < 10000; i++) {
var j = i + 2
}
console.timeEnd()
setTimeout()计时器,在载入后延迟指定时间后,去执行一次表达式,仅执行一次。
setTimeout("alert('Hello!')", 3000 );//3000毫秒后执行
setInterval()在执行时,从载入页面后每隔指定的时间执行代码。
setInterval("clock()",1000)
//或
setInterval(clock,1000)
let与const
-
let 声明的变量只在 let 命令所在的代码块内有效(块级作用域、局部作用),ES6 推荐在函数中使用 let 定义变量,而非 var。
变量 i 是用 var 声明的,在全局范围内有效,所以全局中只有一个变量 i, 每次循环时,setTimeout 定时器里面的 i 指的是全局变量 i ,而循环里的十个 setTimeout 是在循环结束后才执行,所以此时的 i 都是 10。
变量 j 是用 let 声明的,当前的 j 只在本轮循环中有效,每次循环的 j 其实都是一个新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量,即最后输出0~9。(若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值)。
for (var i = 0; i < 10; i++) { setTimeout(function(){ console.log(i); }) } // 输出十个 10 for (let j = 0; j < 10; j++) { setTimeout(function(){ console.log(j); }) } // 输出 0~9
变量 a 用 var 声明存在变量提升,所以当脚本开始运行的时候,a 已经存在了,但是还没有赋值,所以会输出 undefined。
变量 b 用 let 声明不存在变量提升,在声明变量 b 之前,b 不存在,所以会报错。
console.log(a); //undefined var a = "banana"; console.log(b); //ReferenceError: b is not defined let b = "apple";
-
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
const PI = "3.1415926"; console.log(PI); // 3.1415926 const MY_AGE; // SyntaxError: Missing initializer in const declaration
ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。
var PI = "a"; if(true){ console.log(PI); // ReferenceError: PI is not defined const PI = "3.1415926"; }
注意要点
-
let 和const 关键词声明的变量不具备变量提升(hoisting)特性
-
let 和 const 声明只在最靠近的一个块中(花括号内)有效
-
当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
-
const 在声明时必须被赋值
-
const 如何做到变量在声明初始化之后不允许改变的?使用 const 声明复杂类型对象时要慎重。
解构赋值
概述
-
解构赋值是对赋值运算符的扩展。
-
是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
-
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
解构模型
在解构中,有下面两部分参与:
-
解构的源,解构赋值表达式的右边部分。
-
解构的目标,解构赋值表达式的左边部分。
数组模型的结构(Array)
-
基本
let [a, b, c] = [1, 2, 3];
console.log(a, b, c); //1 2 3
-
可嵌套
let [a, [[b], c]] = [1, [[2], 3]]; console.log(a, b, c); //1 2 3
-
可忽略
let [a, , b] = [1, 2, 3]; console.log(a, b); //1 3
-
不完全解构
let [a = 1, b] = []; // a = 1, b = undefined
-
剩余运算符
let [a, ...b] = [1, 2, 3]; console.log(a, b); //a = 1, b = [2,3]
-
字符串
-
在数组的解构中,解构的目标若为可遍历对象,皆可进行解构赋值。可遍历对象即实现 Iterator 接口的数据。
let [a, b, c, d, e] = 'hello'; console.log(a, b, c, d, e); //h e l l o
-
解构默认值
let [a = 2] = [undefined]; // a = 2
当解构模式有匹配结果,且匹配结果是 undefined 时,会触发默认值作为返回结果。
let [a = 3, b = a] = []; // a = 3, b = 3 let [a = 3, b = a] = [1]; // a = 1, b = 1 let [a = 3, b = a] = [1, 2]; // a = 1, b = 2
1. a 与 b 匹配结果为 undefined ,触发默认值:a = 3; b = a =3
2. a 正常解构赋值,匹配结果:a = 1,b 匹配结果 undefined ,触发默认值:b = a =1
3. a 与 b 正常解构赋值,匹配结果:a = 1,b = 2
内置对象的拓展
1.网页会将一些连续传输相同的数据给拦截掉,所以如果有时候我们想连续传给后台数据,可以在数据后面加上实时的时间戳
fn("http://www.xxx.com?email=123&pwd=456")
fn("http://www.xxx.com?email=123&pwd=456&time=" + new Date().getTime())
2.symbol 是一种基本数据类型。Symbol()
函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()
"。
每个从 Symbol()
返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
console.log(typeof symbol1);
// Expected output: "symbol"
console.log(symbol2 === 42);
// Expected output: false
console.log(symbol3.toString());
// Expected output: "Symbol(foo)"
console.log(Symbol('foo') === Symbol('foo'));
// Expected output: false
3.在编程的时候我们可能会用到一些其他进制的数,所以我们可以用一些方法来表示他们
var n = 0b111;//二进制
console.log(n)//十进制
var n2 = 0B101
console.log(n2)//十进制
var n3 = 0o17//八进制
console.log(n3)//十进制
var n4 = 0O10//八进制
console.log(n4)//十进制
还有一种方法能让我们解析其他进制的数变成十进制。parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数,radix
是 2-36 之间的整数,表示被解析字符串的基数。
console.log(parseInt('123'));
// 123 (default base-10)
console.log(parseInt('123', 10));
// 123 (explicitly specify base-10)
console.log(parseInt(' 123 '));
// 123 (whitespace is ignored)
console.log(parseInt('077'));
// 77 (leading zeros are ignored)
console.log(parseInt('1.9'));
// 1 (decimal part is truncated)
console.log(parseInt('ff', 16));
// 255 (lower-case hexadecimal)
console.log(parseInt('0xFF', 16));
// 255 (upper-case hexadecimal with "0x" prefix)
console.log(parseInt('xyz'));
// NaN (input can't be converted to an integer)
对象
(1)对象字面量
-
属性的简洁表示法:ES6允许对象的属性直接写变量,这时候属性名是变量名,属性值是变量值。
const age = 12;
const name = "Amy";
const person = {age, name};
console.log(person); //{age: 12, name: "Amy"}
方法也可以简写:
const person = {
sayHi(){
console.log("Hi");
}
}
person.sayHi(); //"Hi"
-
属性名表达式:ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内。
const obj = { ["he"+"llo"](){ return "Hi"; } } obj.hello(); //"Hi"
(2)对象的扩展运算符
拓展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
-
基本用法
let person = {name: "Amy", age: 15}; let someone = { ...person }; console.log(someone); //{name: "Amy", age: 15}
-
可用于合并两个对象
let age = {age: 15}; let name = {name: "Amy"}; let person = {...age, ...name}; console.log(person); //{age: 15, name: "Amy"}
注意:自定义的属性和拓展运算符对象里面属性的相同的时候
-
自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将被覆盖掉。
let person = {name: "Amy", age: 15}; let someone = { ...person, name: "Mike", age: 17}; console.log(someone); //{name: "Mike", age: 17}
-
自定义的属性在拓展运算度前面,则变成设置新对象默认属性值。
let person = {name: "Amy", age: 15}; let someone = {name: "Mike", age: 17, ...person}; console.log(someone); //{name: "Amy", age: 15}
-
拓展运算符后面是空对象,没有任何效果也不会报错。
let a = {...{}, a: 1, b: 2}; console.log(a); //{a: 1, b: 2}
拓展运算符后面是null或者undefined,没有效果也不会报错
-
let b = {...null, ...undefined, a: 1, b: 2}; console.log(b); //{a: 1, b: 2}
(3)对象的新方法
-
Object.is(value1, value2):用来比较两个值是否严格相等,与(===)基本类似。
-
Object.is("q","q"); // true Object.is(1,1); // true Object.is([1],[1]); // false Object.is({q:1},{q:1}); // false
Map与Set
(1)Map
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
-
Map和Object的区别:
一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。 Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。 Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。 Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
-
Map中的key
-
key是字符串
var myMap = new Map(); var keyString = "a string"; myMap.set(keyString, "和键'a string'关联的值"); myMap.get(keyString); // "和键'a string'关联的值" myMap.get("a string"); // "和键'a string'关联的值" // 因为 keyString === 'a string'
-
key是对象
var myMap = new Map(); var keyObj = {}, myMap.set(keyObj, "和键 keyObj 关联的值"); myMap.get(keyObj); // "和键 keyObj 关联的值" myMap.get({}); // undefined, 因为 keyObj !== {}
-
key是函数
var myMap = new Map(); var keyFunc = function () {}, // 函数 myMap.set(keyObj, "和键 keyObj 关联的值"); myMap.get(keyFunc); // "和键 keyFunc 关联的值" myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
-
key是NaN
var myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" var otherNaN = Number("foo"); myMap.get(otherNaN); // "not a number"
Map特点:有序、键值对(键可以是任意类型)、键名不能重复(如果重复,那么覆盖)
Map的迭代:对Map进行遍历
-
for...of
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
// 将会显示两个 log。 一个是 "0 = zero" 另一个是 "1 = one"
//for...of遍历Map对象,取出每个键值对的键key和值value
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
/* 这个 entries 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的 [key, value] 数组。 */
for (var [key, value] of myMap.entries()) {
console.log(key + " = " + value);
}
/* 这个 keys 方法返回一个新的 Iterator 对象, 它按插入顺序包含了 Map 对象中每个元素的键。 */
for (var key of myMap.keys()) {
console.log(key);
}
/* 这个 values 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的值。 */
for (var value of myMap.values()) {
console.log(value);
}
forEach()
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
// 将会显示两个 logs。 一个是 "0 = zero" 另一个是 "1 = one"
myMap.forEach(function(value, key) {
console.log(key + " = " + value);
}, myMap)
Map对象的操作
-
Map 与 Array的转换
var kvArray = [["key1", "value1"], ["key2", "value2"]]; //二维数组
// Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象
var myMap = new Map(kvArray);
console.log(myMap); //Map(2) {"key1" => "value1", "key2" => "value2"}
// 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组
var outArray = Array.from(myMap);
console.log(outArray); //[["key1", "value1"], ["key2", "value2"]]
-
Map的克隆
var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]);
var myMap2 = new Map(myMap1);
console.log(myMap1 === myMap2);
// 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。
-
Map的合并
var first = new Map([[1, 'one'], [2, 'two'], [3, 'three']]); var second = new Map([[1, 'uno'], [2, 'dos']]); // 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的,对应值即 uno,dos, three var merged = new Map([...first, ...second]);
(2)Set
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
-
Set中的特殊值
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:+0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
undefined 与 undefined 是恒等的,所以不重复;
NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
let mySet = new Set();
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5} 这里体现了值的唯一性
mySet.add("some text");
// Set(3) {1, 5, "some text"} 这里体现了类型的多样性
var o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2});
// Set(5) {1, 5, "some text", {…}, {…}}
// 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储
类型转换
-
Array
// Array 转 Set
var mySet = new Set(["value1", "value2", "value3"]);
// 用...操作符,将 Set 转 Array
var myArray = [...mySet];
-
String
// String 转 Set
var mySet = new Set('hello');
console.log(mySet);// Set(4) {"h", "e", "l", "o"}
// 注:Set 中 toString 方法是不能将 Set 转换成 String
Set对象作用
数组去重
var mySet = new Set([1, 2, 3, 4, 4]);
并集
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var union = new Set([...a, ...b]); // {1, 2, 3, 4}
交集
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}
差集
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var difference = new Set([...a].filter(x => !b.has(x))); // {1}