let只作用在当前块级作用域内
使用let或者const声明的变量,不能再被重新声明
let不存在`变量提升`
console.log(dad); var dad = '我是爸爸!';//预定义undefined console.log(dad); let dad = '我是爸爸!';//报错
生成十个按钮 每个按点击的时候弹出1 - 10
var 方法:
var i = 0; for (i = 1; i <= 10; i ++) { (function(i) { var btn = document.createElement('button'); btn.innerText = i; btn.onclick = function() { alert(i) }; document.body.appendChild(btn); })(i); }
let方法:
for (let i = 1; i <= 10; i ++) { var btn = document.createElement('button'); btn.innerText = i; btn.onclick = function() { alert(i) }; document.body.appendChild(btn); }
ES6之前的作用域:全局作用域、函数作用域、eval作用域、ES6块级作用域
常量声明后不能被修改
const NAME = '小明'; NAME = '小红';//报错
q: 怎么防止常量为引用类型的时候能被修改的情况
Object.freeze()
const xiaoming = { age: 14, name: '小明' }; Object.freeze(xiaoming); console.log(xiaoming); xiaoming.age = 22; xiaoming.dd = 11; console.log(xiaoming); const ARR = []; Object.freeze(ARR); ARR.push(1); console.log(ARR);
Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性
var obj1 = { a: 1, b: 2 } var obj2 = Object.create(obj1); obj2.c = 3; obj2.d = 4; for (let i in obj2) { if (obj2.hasOwnProperty(i)) { document.body.innerHTML += (i + ': ' + obj2[i] + '<br>'); } }
数组的解构赋值
const arr = [1, 2, 3, 4]; let [a, b, c, d] = arr; console.log(a);
更复杂的匹配规则
const arr = ['a', 'b', ['c', 'd', ['e', 'f', 'g']]]; const [ , b] = arr; const [ , , g] = ['e', 'f', 'g'] const [ , , [ , , g]] = ['c', 'd', ['e', 'f', 'g']]; const [ , , [ , , [ , , g]]] = arr;
扩展运算符 ...
const arr1 = [1, 2, 3]; const arr2 = ['a', 'b']; const arr3 = ['zz', 1]; const arr4 = [...arr1, ...arr2, ...arr3]; const arr = [1, 2, 3, 4, 5, 6]; const [a, b, ...c] = arr;
默认值
const arr = [1, null, undefined]; const [a, b = 2, c, d = 'aaa'] = arr;
交换变量
[a, b] = [b, a];
接收多个函数返回值
function getUserInfo(id) { // .. ajax return [ true, { name: '小明', gender: '女', id: id }, '请求成功' ]; }; const [status, data, msg] = getUserInfo(123);
对象的解构赋值
const obj = { saber: '阿尔托利亚', archer: '卫宫' }; const { saber, archer1 } = obj;
稍微复杂的解构条件
const player = { nickname: '感情的戏∫我没演技∆', master: '东海龙王', skill: [{ skillName: '龙吟', mp: '100', time: 6000 },{ skillName: '龙卷雨击', mp: '400', time: 3000 },{ skillName: '龙腾', mp: '900', time: 60000 }] }; const { nickname } = player; const { master } = player; const { skill: [ skill1, { skillName }, { skillName: sklName } ] } = player; const { skill } = player; const [ skill1 ] = skill;
结合扩展运算符
const obj = { saber: '阿尔托利亚', archer: '卫宫', lancer: '瑟坦达' }; const { saber, ...oth } = obj;
对已经申明了的变量进行对象的解构赋值
let age; const obj = { name: '小明', age: 22 }; ({ age } = obj);
默认值
let girlfriend = { name: '小红', age: undefined, }; let { name, age = 24, hobby = ['学习'] } = girlfriend;
字符串的结构赋值
const str = 'I am the bone of my sword'; // 我是剑骨头 const [ a, b ,c, ...oth ] = str; const [ ...spStr1 ] = str;
提取属性
const { length, split } = str;
数值与布尔值的解构赋值
const { valueOf: vo } = 1; const { toString: ts } = false;
函数参数的解构赋值
function swap([x, y]) { return [y, x]; }; let arr = [1, 2]; arr = swap(arr);
function Computer({ cpu, memory, software = ['ie6'], OS = 'windows 3.5' }) { console.log(cpu); console.log(memory); console.log(software); console.log(OS); }; new Computer({ memory: '128G', cpu: '80286', OS: 'windows 10' });
最后来一个高颜值弹框小案例~
按照国际惯例先放图
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="./msg.css"> </head> <body> <button>弹个框</button> <div id="t"></div> <script src="./msg.js"></script> <script> document.querySelector('button').addEventListener('click', function() { new $Msg({ content: '真的要删除吗...', title: '确认删除', type: 'wrong', btnName: ['好的', '算了吧'], confirm: function(e) { console.log(this); console.log(e); new $Msg({ content: '删除成功<span style="color: red">~</span>', type: 'success', footer: false, useHTML: true, header: false }) }, cancel: function(e) { document.querySelector('#t').innerHTML += '取消了,'; } }); }); </script> </body> </html>
msg.css
/* 弹出框最外层 */ .msg__wrap { position: fixed; top: 50%; left: 50%; z-index: 10; transition: all .3s; transform: translate(-50%, -50%) scale(0, 0); max-width: 50%; background: #fff; box-shadow: 0 0 10px #eee; font-size: 10px; } /* 弹出框头部 */ .msg__wrap .msg-header { padding: 10px 10px 0 10px; font-size: 1.8em; } .msg__wrap .msg-header .msg-header-close-button { float: right; cursor: pointer; } /* 弹出框中部 */ .msg__wrap .msg-body { padding: 10px 10px 10px 10px; display: flex; } /* 图标 */ .msg__wrap .msg-body .msg-body-icon{ width: 80px; } .msg__wrap .msg-body .msg-body-icon div{ width: 45px; height: 45px; margin: 0 auto; line-height: 45px; color: #fff; border-radius: 50% 50%; font-size: 2em; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success{ background: #32a323; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success::after{ content: "成"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong{ background: #ff8080; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong::after{ content: "误"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info{ background: #80b7ff; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info::after{ content: "注"; } /* 内容 */ .msg__wrap .msg-body .msg-body-content{ min-width: 200px; font-size: 1.5em; word-break: break-all; display: flex; align-items: center; padding-left: 10px; box-sizing: border-box; } /* 弹出框底部 */ .msg__wrap .msg-footer { padding: 0 10px 10px 10px; display: flex; flex-direction: row-reverse; } .msg__wrap .msg-footer .msg-footer-btn { width: 50px; height: 30px; border: 0 none; color: #fff; outline: none; font-size: 1em; border-radius: 2px; margin-left: 5px; cursor: pointer; } .msg__wrap .msg-footer .msg-footer-cancel-button{ background-color: #ff3b3b; } .msg__wrap .msg-footer .msg-footer-cancel-button:active{ background-color: #ff6f6f; } .msg__wrap .msg-footer .msg-footer-confirm-button{ background-color: #4896f0; } .msg__wrap .msg-footer .msg-footer-confirm-button:active{ background-color: #1d5fac; } /* 遮罩层 */ .msg__overlay { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 5; background-color: rgba(0, 0, 0, .4); transition: all .3s; opacity: 0; }
msg.js
(function (window, document) { /** * 暴露出去的构造函数 * @param {*} options */ let Msg = function (options) { this._init(options); } /** * 初始化传入的配置后创建元素 并显示 * @param {*} param0 */ Msg.prototype._init = function ({ content = '', type = 'info', useHTML = false, showIcon = true, confirm = null, cancel = null, footer = true, header = true, title = '提示', contentStyle = {}, contentFontSize = '1.5em', btnName = ['确定', '取消'] }) { this.content = content; this.type = type; this.useHTML = useHTML; this.showIcon = showIcon; this.confirm = confirm; this.cancel = cancel; this.footer = footer; this.contentStyle = contentStyle; this.contentFontSize = contentFontSize; this.title = title; this.btnName = btnName; this.header = header; this._createElement(); // 给dom上的按钮们和遮罩层绑定事件 this._bind({ el: this._el, overlay: this._overlay }); this._show({ el: this._el, overlay: this._overlay }); } /** * 创建弹出框 */ Msg.prototype._createElement = function () { let wrap = document.createElement('div'); wrap.className = 'msg__wrap'; const [ confirmBtnName, cancelBtnName ] = this.btnName; // 判断是否显示图标 const iconHTML = this.showIcon ? '<div class="msg-body-icon"> <div class="msg-body-icon-' + this.type + '"></div> </div>' : ''; // 判断是否显示弹出框底部按钮 const footerHTML = this.footer ? '<div class="msg-footer"> <button class="msg-footer-btn msg-footer-cancel-button">' + cancelBtnName + '</button> <button class="msg-footer-btn msg-footer-confirm-button">' + confirmBtnName + '</button> </div>' : ''; const headerHTML = this.header ? '<div class="msg-header"> <span>' + this.title + '</span> <span class="msg-header-close-button">×</span> </div>' : ''; // 拼成完整html const innerHTML = headerHTML + '<div class="msg-body">' + iconHTML + '<div class="msg-body-content"></div> </div>' + footerHTML; // 将容器内的html替换成弹出框内容 wrap.innerHTML = innerHTML; // 生成合并自定义的内容样式 const contentStyle = { fontSize: this.contentFontSize, ...this.contentStyle } // 获取内容dom let content = wrap.querySelector('.msg-body .msg-body-content'); // 给内容容器加上自定义样式 for (let key in contentStyle) { content.style[key] = contentStyle[key]; } // 给弹出框内容赋值 if (this.useHTML) { content.innerHTML = this.content; } else { content.innerText = this.content; } // 创建遮罩层 let overlay = document.createElement('div'); overlay.className = 'msg__overlay'; // 把dom挂到当前实例上 this._overlay = overlay; this._el = wrap; } /** * 显示弹出框 * @param {*} param0 */ Msg.prototype._show = function ({ el, overlay }) { // 把遮罩和弹出框插到页面中 document.body.appendChild(el); document.body.appendChild(overlay); // 显示 setTimeout(function () { el.style.transform = 'translate(-50%, -50%) scale(1, 1)'; overlay.style.opacity = '1'; console.log(1); }); console.log(2); } /** * 绑定事件 * @param {*} param0 */ Msg.prototype._bind = function ({ el, overlay }) { // 保留this const _this = this; // 隐藏弹出框 const hideMsg = function () { _this._el.style.transform = 'translate(-50%, -50%) scale(0, 0)'; _this._overlay.style.opacity = '0'; setTimeout(function () { document.body.removeChild(_this._el); document.body.removeChild(_this._overlay); }, 300); } // 取消事件 const close = function (e) { _this.cancel && _this.cancel.call(_this, e); hideMsg(); } // 确定事件 const confirm = function (e) { _this.confirm && _this.confirm.call(_this, e); hideMsg(); } overlay.addEventListener('click', close); if (this.header) { el.querySelector('.msg-header .msg-header-close-button').addEventListener('click', close); } if (this.footer) { el.querySelector('.msg-footer .msg-footer-cancel-button').addEventListener('click', close); el.querySelector('.msg-footer .msg-footer-confirm-button').addEventListener('click', confirm); } } // 注册到全局对象 window.$Msg = Msg; })(window, document);