做了一段时间的VUE。。。真心都是连猜带蒙的。。。一直写后端,突然变成前端好多东西感觉都不会,基础也差,今天找了本书,看了下。。。哎。。。。
1.用let 声明的变量只在它所在的代码块有效。
{
var a = "a"
let b = "b"
}
console.log(a)
console.log(b)//-----------b is not defined b未定义
2.var 命令支持“变量提升” let不支持
{
console.log(c1)
console.log(c2)//Cannot access 'c2' before initialization 初始化前无法访问“c2”
var c1 = "c1"
let c2 = "c2"
}
3.在相同的作用域 let不能声明相同的变量,var是可以的
{
var c1 = "c1"
var c1 = "c2"
console.log(c1)//------------c2
let c1 = "c3"//------------- Identifier 'c1' has already been declared 标识符“c1”已声明
}
4.const 的作用域只在声明所在的块级作用域内有效,不支持变量提升 ,不可重复声明。 是常量指向的那个内存地址不得改
const i = 0;
//i = 999;//-------------Assignment to constant variable. 常量变量赋值。
//const foo//-------------Missing initializer in const declaration 常量声明中缺少初始值设定项
const par = {}
par.name = 'cmh'
par.age = 100
par.sex = true
console.log(par)//----------------{name: "cmh", age: 100, sex: true}
//par = {}//Assignment to constant variable.---------常量变量赋值。
const a = []
a.push('Hello');
//a.length = O; //O is not defined
a = ['Dave']//Assignment to constant variable.---------常量变量赋值。
5.赋值 这种写法属于“模式匹配”,只要等号两边的模式相同, 左边的变量就会被赋予对应的值。
{
//传统
let a = 1
let b = 2
let c = 3
console.log(a)//1
console.log(b)//2
console.log(c)//3
//ES6
let [a1,b1,c1] = [1,2,3]
console.log(a1)//1
console.log(b1)//2
console.log(c1)//3
//let [a2 = 1, b2 = 2, c2 = 3]//--------------------如果不加[] Missing initializer in destructuring declaration解构声明中缺少初始值设定项
let [a2 = 1, b2 = 2, c2 = 3] = []
console.log("a2",a2)//1
console.log("b2",b2)//2
console.log("c2",c2)//3
let [x, , y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 3
let [aa, [[bb], cc]] = [1, [[2], 3]];
console.log(aa); // 1
console.log(bb); // 2
console.log(cc); // 3
let [x1] = [, 2, 3];
console.log(x1); // undefined -------------------解构不成功, 变量的值就等于undefined
let [isshow=true]=[]
console.log(isshow);// true
let [x2, y2 = 'b'] = ['a']
console.log("x2",x2);// a
console.log("y2",y2);// b
//ES6 内部使用严格相等运算符(===)来判断一个位置是否有值,所以只有当一个数组成员严格等于undefined , 默认值才会生效。一个数组成员是null , 默认值就不会生效
let [x3 =1] = [undefined];
console.log("x3", x3);//1
let [x4 = 1] = [null];
console.log("x4", x4);//null
//解构不仅可以用于数组,还可以用于对象。对象的解构与数组的解构有一个重要的不同: 数组的元素是按次序排列的,变量的取值由它的位置决定: 而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { x5, x6 } = { x6: "aaa", x5: "bbb" };
console.log(x6) // aaa
console.log(x5) // bbb
//先找到同名属性, 再赋给对应的变量。真正被赋值的是后者,而不是前者。
let { x7: F, x8: L } = { x7: "aaa", x8: "bbb" }
console.log("F",F) // aaa
console.log("L",L) // bbb
//等价于
let obj = { x77: 'aaa', x88: 'bbb' }
let { x77: FF, x88: LL } = obj;
console.log("FF",FF) // 'hello'
console.log("LL",LL) // 'world'
// x7/x77 是匹配的模式, F/FF 才是变量。真正被赋值的是变量F/FF ,而不是模式x7/x77 。
}
6.for
for是同步操作,而for 循环内部的函数执行的是异步操作,当函数执行找不到i 时,便会往上面的作用域查找,所以i 的值为5 , 最后打印的都是“这是第5 个按钮”。改为let即可
var btns = document.querySelectorAll('button');
//var i
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
console.log("这是第"+ i +"个按钮")
}
}
//这是第5个按钮 ...一直是
//let i
for (let i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
console.log("这是第" + i + "个按钮")
}
}
//这是第1个按钮 这是第2个按钮 这是第3个按钮 ...
7.箭头函数
这个当时也是不清楚,开发当中坑了好久。
{
const User = {
name: '欢哥',
say: function () {
setInterval(function () {
console.log('我是' + this.name + "我怕谁")
},1000)
}
}
//我是我怕谁
//??????????????????
//setlnterval 是在全局作用域下执行的,所以this 指向的是全局window ,而window 上没有mame所以输出的是undefined或""
const User = {
name: '欢哥',
say: function () {
let that = this;
setInterval(function () {
console.log('我是' + that.name + "我怕谁")
}, 1000)
}
}
//我是欢哥我怕谁
//为了简化代码 产生了箭头函数
//(参数l, 参数2, … ,参数N) => { 函数声明 }
//(参数1 ,参数2,…,参数N)=>表达式(单一)
//() => { 函数声明 }
const User = {
name: '欢哥',
say: function(){
setInterval(() => {
console.log('我是' + this.name + "我怕谁")
}, 1000)
}
}
User.say();
//箭头函数的this 在定义的时候就确定了,以后不管如何调用箭头函数,箭头函数的this 始终为定义时的this 。
}
两次this输出:
8.Map K/V 键值对
{
const map = new Map([
['name', '张三'],
['title', 'Author']
]);
console.log(map);//{"name" => "张三", "title" => "Author"}
//成员总数
console.log(map.size);//2
//SET 添加/更新
map.set('tttt', ['大花', '二狗']).set('edition', 6)
//set 方法设置键名key 对应的键值为value ,然后返回整个Map 结构。
//如果key 己经有对应的键值,则键值会被更新,否则就新生成键值。则方法返回的是当前的Map对象, 因此可以采用链式写法
console.log(map);//{"name" => "张三", "title" => "Author", "tttt" => Array(2), "edition" => 6}
//GET 获取
console.log(map.get('name'));//张三
console.log(map.get('name111'));//undefined
//has 判断存在
console.log(map.has('name'));//true
console.log(map.has('name111'));//false
//删除
map.delete('name')
console.log(map);//{"title" => "Author", "tttt" => Array(2), "edition" => 6}
//遍历
//keys():返回键名的遍历器。
//values():返回键值的遍历器。
//entries():返回所有成员的遍历器。
//forEach() : 遍历Map 的所有成员。
console.log("keys()");
for (let key of map.keys()) {
console.log(key);
}
console.log("values()");
for (let key of map.values()) {
console.log(key);
}
console.log("entries()");
for (let [key,value] of map.entries()) {
console.log(key, value);
}
console.log("forEach()");
map.forEach(function (value, index) {
console.log(index + '.'+ value);
// name:张三
// title:Author
})
}
9.模块(module)
在创建或者使用对应的js 文件时常用export 命令导出对应的属性和方法、import 命令导入对应的属性和方法。
- export
一个模块就是一个独立的文件,文件内部的所有变量外部无法获取。如果希望外部能够读取模块内部的某个变量,就必须使用export 关键字输出该变量。
2.import
使用export 命令定义模块的对外接口以后,其他JS 文件就可以通过import 命令加载这个模块。import 命令用于加载其他的文件,并从中输入变量。import 命令接受一对大括号,里面指定要从其他模块导入的变量名(或者函数名),大括号里面的变量名必须与被导入模块对外接口的名称相同。
//第一种写法
export var firstName = 'Michael'
export var lastName = 'Jackson'
export var year = 1958
export function ljfunc(x, y, z) {
return x + y + z;
}
//第二种写法
var firstName = 'Michael'
var lastName = 'Jackson'
var year = 1958;
function ljfunc(x, y, z) {
return x + y + z;
}
export default { firstName, lastName, year, ljfunc }
<script type="module">//type必须是"module" Cannot use import statement outside a module 不能在模块外使用import语句
import module2 from '/Scripts/api/module2.js'
import { firstName, lastName, year, ljfunc } from '/Scripts/api/module1.js'
console.log(module2.firstName)
console.log(module2.lastName)
console.log(module2.year)
console.log(module2.ljfunc('1', '2', '3'))
console.log(firstName)
console.log(lastName)
console.log(year)
console.log(ljfunc('1', '2', '3'))
</script>
…
三个点差点忘记了,应用还是挺多的。
vuex的…mapGetters([‘isRender’])和…mapActions({ upuser:‘updateuser’, clearuser:‘clearuser’})
…数组、对象 等操作
...数组
let iArray = ['1', '2', '3']
console.log(...a)
1 2 3
-----------------------------------------------
数组组合
let b = ['1', '2', '3']
console.log(['0', ...b, '4'])
(5) ["0", "1", "2", "3", "4"]
var c = [0, 1, 2]
var d = [3, 4, 5]
方式1
c.push(...d)
(6) [0, 1, 2, 3, 4, 5]
方式2
[...c, ...d]
(6) [0, 1, 2, 3, 4, 5]
-----------------------------------------------
数组删除
const [first, ...data] = [1, 2, 3, 4, 5];
console.log(first);
console.log([...data]);
1
(4) [2, 3, 4, 5]
const [...data,last] = [1, 2, 3, 4, 5];
此处会报异常
Rest element must be last element rest元素必须是最后一个元素
...data 必须是数组最后一个元素
-----------------------------------------------
字符串转数组
let Str = 'abcdefg123'
console.log([...Str])
(10) ["a", "b", "c", "d", "e", "f", "g", "1", "2", "3"]
-----------------------------------------------
数组最大值
let e = [100,11, 22, 33, 44, 55, 66, 77, 88, 99]
let maxnum = Math.max(...e)
console.log(maxnum)
最大值 100
-----------------------------------------------
操作对象
添加属性
var a = { age: 36, sex: '男' }
var c = { name: '熙之', ...a }
console.log(c)
{name: "熙之", age: 36, sex: "男"}
修改属性
var d = { ...a, name: '陈熙之' }
console.log(d)
{age: 36, sex: "男", name: "陈熙之"}
删除属性
let { name, ...f } = d
console.log(f)
{age: 36, sex: "男"}
-----------------------------------------------
console.log("类型转换")
// 强制转换为Boolean 用 !!
var bool = !!"c";
console.log(bool); // true
console.log(typeof bool); // boolean
// 强制转换为Number 用 +
var num = +"1234";
console.log(num); // 1234
console.log(typeof num); // number
// 强制转换为String 用 ""+
var str = "" + 1234;
console.log(str); // '1234'
console.log(typeof str); // string
Promise 异步
var text = 'test'
new Promise((resolve, reject) => {
setTimeout(() => {
//console.log(resolve())
resolve(text)
}, 1000);
}).then((data) => {
console.log(data+'1');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(text)
}, 1000);
})
}).then((data) => {
console.log(data+'2');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(text)
}, 1000);
})
}).then((data) => {
console.log(data+'3');
})
解决类似以下问题