let变量声明及声明特性
声明变量:
let a;
let b,c,d;
let e = 100;
let f = 521, g = 'hello', h = [];
特性:
- 变量不能重复声明(防止变量污染)
//ES6
let star = 'a';
let star = 'b'; //报错
//ES5
var str = 'abc';
var str = 'def'; //不报错
- 块级作用域(ES5:全局、函数、eval)
{
let a = 12;
}
console.log(a); //报错
//if else while for块级作用域中同样有效
- 不存在变量提升
//ES6
console.log(song); //报错
let song = 'Maria';
//ES5
console.log(song); //undefined
var song = 'Maria';
- 不影响作用域链
{
let school = 'XUPT';
function fn(){
console.log(school);
}
fn(); //XUPT
}
实例:
点击一个div使其背景颜色变为粉色
let items = document.getElementsByClassName('item');
//使用var
//若使用itmes[i].style.background,则点击任意一个div都不会变色,i在全局作用域中,循环后会增加变为3
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
this.style.background = 'pink';
}
}
console.log(window.i); //3
//使用let
for(let i = 0; i < items.length; i++){
items[i].onclick = function(){
itmes[i].style.background = 'pink';
}
}
const声明常量以及特点
声明常量:
const SCHOOL = 'XUPT';
特点:
- 一定要赋初始值
const A; //报错
- 一般常量使用大写(潜规则)
- 常量的值不可修改,不可重复声明
const SCHOOL = 'XUPT';
SCHOOL = 'ABC'; //报错
const SCHOOL = 'SSS'; //报错
- 块级作用域
{
const PLAYER = 'UZI';
}
console.log(PLAYER); //报错
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ['UZI','MLXG','Ming','letme'];
TEAM.push('Meki0'); //虽然数组内容变化,但常量保存的地址未变,故不会报错
TEAM = 100; //报错
本质:const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
- 对于简单数据类型(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。
- 对于符合类型数据(主要是对象和数值)而言,变量指向的内存地址保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,完全不能控制。
顶层对象的属性:
- var,function命令声明的全局变量依旧是顶层对象的属性。
- let,const,class命令声明的全局变量不属于顶层对象的属性。
var a = 1;
console.log(window.a); //1
let b = 1;
console.log(window.b); //undefined
变量的解构赋值
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称作解构赋值。
- 数组的解构赋值
const F4 = ['老王','老李','老张','老邓'];
let [wang,li,zhang,deng] = F4;
console.log(wang); //老王
console.log(li); //老李
console.log(zhang); //老张
console.log(deng); //老邓
- 对象的解构赋值
const wang = {
name: '老王',
age: 30,
job: function(){
concole.log('programmer');
}
}
let {name,age,job} = wang;
console.log(name); //老王
console.log(age); //30
console.log(job); //fn()
job(); //programmer
模板字符串
ES6引入新的声明字符串方式 ``
反引号。(ES5:''
,""
)
面向对象
原来写法
- 类和构造函数一样
- 属性和方法分开写的
// 老版本
function User(name, pass) {
this.name = name;
this.pass = pass;
}
User.prototype.showName = function () {
console.log(this.name);
}
User.prototype.showPass = function () {
console.log(this.pass);
}
var u1 = new User('able', '1233');
u1.showName(); //able
u1.showPass(); //1233
// 老版本继承
function VipUser(name, pass, level) {
User.call(this, name, pass)
this.level = level;
}
VipUser.prototype = new User();
VipUser.prototype.constructor = VipUser;
VipUser.prototype.showLevel = function () {
console.log(this.level);
}
var v1 = new VipUser('blue', '1234', 3);
v1.showName(); //blue
v1.showPass(); //1234
v1.showLevel(); //3
版面向对象
- 有了 class 关键字、构造器
- class 里面直接加方法
- 继承,super 超类==父类
//新版本
class User {
constructor(name, pass) {
this.name = name;
this.pass = pass;
}
showName() {
console.log(this.name);
}
showPass() {
console.log(this.pass);
}
}
var u1 = new User('able2', '111');
u1.showName(); //able2
u1.showPass(); //111
// 新版本继承
class VipUser extends User {
constructor(name, pass, level) {
super(name, pass);
this.level = level;
}
showLevel(){
console.log(this.level);
}
}
v1 = new VipUser('blue', '123', 3);
v1.showLevel(); //3
JSON
1.JSON 格式
- JavaScript Object Notation 的缩写,是一种用于数据交换的文本格式
- JSON 是 JS对象 的严格子集
- JSON 的标准写法:
- 只能用双引号
- 所有的key都必须用双引号包起来
2.JSON 对象
- JSON 对象是 JavaScript 的原生对象,用来处理 JSON 格式数据,有两个静态方法
- JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象。
- JSON.stringify(obj) :接受一个 JavaScript 对象并将其转换为一个 JSON 字符串。
//JSON.stringify(obj)将对象转化为字符串
var json = {a: 12, b: 5};
var str = 'hi,' + JSON.stringify(json);
var url = 'http://www.xx.com/' + encodeURIComponent(JSON.stringify(json));
console.log(str); //hi,{"a":12,"b":5}
console.log(url); //http://www.xx.com/%7B%22a%22%3A12%2C%22b%22%3A5%7D
//JSON.parse(string)将字符串转化为对象
var str = '{"a": 12, "b": 4, "c": "abc"}';
var json = JSON.parse(str);
console.log(json); //{ a: 12, b: 4, c: 'abc' }
3.对象 简写
- 名字和值(key-value) 一样时可以简写,留一个就行
- 里面的函数可以简写, 去掉:function
var a = 12, b = 5;
console.log({a:a, b:b}); //{ a: 12, b: 5 }
console.log({a, b}); //{ a: 12, b: 5 }
console.log({a, b, c:"c"}); //{ a: 12, b: 5, c: 'c' }
console.log({ a, b, show(){ console.log('a') }});
//{ a: 12, b: 5, show: [Function: show] }
Promise
1.异步和同步
- 异步:操作之间没有关系,同时执行多个操作, 代码复杂
- 同步:同时只能做一件事,代码简单
2.Promise 对象
- 用同步的方式来书写异步代码
- Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
- 改善了可读性,对于多层嵌套的回调函数很方便
- 充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口
3.Promise 也是一个构造函数
- 接受一个回调函数f1作为参数,f1里面是异步操作的代码
- 返回的p1就是一个 Promise 实例
- 所有异步任务都返回一个 Promise 实例
- Promise 实例有一个then方法,用来指定下一步的回调函数
function f1(resolve, reject) {
// 异步代码...
}
var p1 = new Promise(f1);
p1.then(f2); // f1的异步操作执行完成,就会执行f2
4.Promise 使得异步流程可以写成同步流程
// 传统写法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
});
// Promise 的写法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
5.Promise.all(promiseArray)方法
- 将多个Promise对象实例包装,生成并返回一个新的Promise实例
- promise数组中所有的promise实例都变为resolve的时候,该方法才会返回
- 并将所有结果传递results数组中
- promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象
var p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // [1, 2, 3]
});
6.Promise.race([p1, p2, p3])
- Promse.race就是赛跑的意思
- 哪个结果获得的快,就返回那个结果
- 不管结果本身是成功状态还是失败状态
generator-生成器函数
- 普通函数,一路到底
- generator函数,中间可以停,到哪停呢,用 yield 配合,交出执行权
- yield 有 放弃、退让、退位的意思
- 需要调用next()方法启动执行,需要遇到 yield 停, 踹一脚走一步
- generator函数前面加一个 * 两边可以有空格,或靠近函数或function
- 背后实际生成多个小函数,实现走走停停
function show() {
console.log('a')
console.log('b')
}
show() // 普通函数
function *show2() {
console.log('1')
yield
console.log('2')
}
let genObj = show2()
genObj.next() // 1
genObj.next() // 2
genObj.next() // 最后了,没有结果
generator-yield
1.yield
- 既可传参,又可以返回
- 第一个next()传参无效,只用来启动
2.如果函数前漏掉 *
- 就是普通函数
- 如果有yield会报错, ReferenceError: yield is not defined
- yield 只能在Generator函数内部使用
function * show() {
console.log('1')
var a = yield
console.log('2')
console.log(a)
}
// yield 传参
var gen = show()
gen.next() // 1
gen.next() // 2 和 undefined 因为没有传参,yield没有返回值
var gen = show()
gen.next(10) // 1 第一次执行到yield,但没有执行赋值
gen.next(20) // 2 和 20
function* show2() {
console.log('1')
yield 10
console.log('2')
}
// yield 返回
var gen = show2()
var res1 = gen.next()
console.log(res1) // { value: 10, done: false }
var res2 = gen.next()
console.log(res2)
// { value: undefined, done: true } 最后的value需要return返回
generator-实例
- Promise 适合一次读一组
- generator 适合逻辑性的
// 带逻辑-generator
runner(function * () {
let userData = yield $.ajax({url: 'getUserData'})
if (userData.type == 'VIP') {
let items = yield $.ajax({url: 'getVIPItems'})
} else {
let items = yield $.ajax({url: 'getItems'})
}
})
// yield 实例,用同步方式写异步
server.use(function * () {
let data = yield db.query(`select * from user_table`)
this.body = data
})