var 与 let,const 的区别
var
- 可以重复声明
- 无法限制修改
- 没有/忽略 块级作用域
因此,即使在块级作用域内定义的变量,在块级作用域外仍然能被访问。
这源于通过var声明的变量实际上总是在距离最近的函数内或全局作用域中注册的,
不关注块级作用域。
与 var 不同,
let 和 const 是直接在最近的词法环境中定义变量
(可以是“块级作用域内、循环体内、函数内、全局环境内”)。因此,我们可以使用 let 和 const 定义块级别、函数级别、全局级别的变量。
let : 不能重复声明,变量-可以修改,定义自身的块级作用域 const : 不能重复声明,常量-不能修改,块级作用域 。
代码语言:javascript复制for( let i=0;i<10;i ){
}
console.log(i);//error, i is not defined
代码语言:javascript复制const FLAG= true;//使用const定义的全局静态变量,常使用大写表示
FLAG = false;
console.log(FLAG); // ture
const 变量的特性:
代码语言:javascript复制const objConst = {};
objConst.name = 'imaginecode';
即:const 变量只能在声明时被初始化一次,之后再也不允许将全新的值赋给 const变量。但是,仍然可以修改 const 变量已经存在的值,只是不能重写 const 变量。
因为对象是引用类型的,objConst 中保存的仅是对象的指针,这就意味着,const 仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。也就是说 const 定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的。
函数
箭头函数——一种简写
注意,在箭头函数中,this 指向的上下文环境与普通函数中的this有着显著的区别:
- 普通函数:谁调用 this,this 就指向谁
- 箭头函数:this 在哪个环境中,this 就指向谁
例如:
代码语言:javascript复制class Demo(){
construct(){
}
handle1 =()=>{
this.handle2()
}
handle2 =()=> {
let html =`<a href="javascript:;" class="btn2">btn2</a>`;
$('body').append(html);
$('.btn2').click(()=>{return this.handle1()}); //this指向Demo
$('.btn2').click(function(){this.handle1()}); //undefined ,this指向 类名为btn2 的 a 标签
}
}
function 去掉 ,加=>
代码语言:javascript复制#es5
function () {
}
#es6
()=>{
}
- 如果只有一个参数,()可以省
- 如果只有一个 return,return 和花括号 {} 可以省
window.onload = function() {
alert('abc);
};
#es6
window.onload = ()=> {
alert('abc');
};
参考
- https://segmentfault.com/a/1190000011194676#articleHeader2
- https://www.liaoxuefeng.com/wiki/1022910821149312/1031549578462080
函数的参数
- 参数的扩展/展开
- 默认参数
参数扩展
- 搜集剩余的参数(Rest Parameter),但必须是最后一个
function show(a,b,...args) {
alert(a);
alert(b);
alert(args);//args = [3,4,5,6]
}
show(1,2,3,4,5,6);
展开数组
- 展开后的效果,跟直接把数组的内容写在这儿
let arr=[1,2,3];
show(...arr); //==show(1,2,3)
function(a,b,c){
}
默认参数
- 可传可不传,传递就听你的,不传递就按默认的。
function show(a,b=1,c=2){//b=1,c=2默认参数
console.log(a,b,c);
}
show(7,8,9);//result: 7,8,9
解构赋值
在传统的js中,数组字面量 是不能出现在等于号(复制操作符)左边的。解构赋值的语法是把等于号右边数组中包含的值,分别赋值给等于号左边数组中的变量。
例如:
代码语言:javascript复制//数组
var [,value] = ["color","red"];
console.log(value);//"red"
//对象
var person = {
name:"imaginecode",
age: 17
}
var {name:personName,age:personAge} = person;
console.log(personName);//"imaginecode"
console.log(personAge);//17
简单理解,解构=“拆”
- 左右两边结构必须一样
- 右边必须是个东西
- 声明和赋值不能分开,必须在一句话里面
let arr=[1,2,3];
#解构赋值
let [a,b,c]=[1,2,3];//左右两边必须一样
代码语言:javascript复制let {a,b,c}={a:1,b:2,c:3};//json
let [{a,b,c},[n1,n2,n3],num,str]=[{a:1,b:2},[1,2,3],1,'abc'];
# 等同
let [json,arr,num,str][{a:1,b:2},[1,2,3],1,'abc'];
console.log(json,arr,num,str);
数组
四个新方法
- map 映射:一个对一个
- reduce 汇总:一堆出来一个
- filter 过滤器
- forEach 循环(迭代)
map
代码语言:javascript复制let arr = [1,2,3];
let result = arr.map(function(item){
return item*2;
});
alert(result);
# 箭头函数改写
let result = arr.map(item=>item*2);
reduce
代码语言:javascript复制# 求和
let arr = [1,2,3,4,5,6];
let result = arr.reduce(function(tmp,item,index){
return tmp item;
//tmp:中间结果
//item:arr中的元素,index:下标
});
alert(result);
代码语言:javascript复制# 求平均数
let arr = [1,2,3,4,5,6];
let result = arr.reduce(function(tmp,item,index){
if(index!=arr.length-1){//不是最后一个
return tmp item;
}else {//是最后一个数
return (tmp item)/arr.length;
}
});
alert(result);
filter
代码语言:javascript复制let arr = [1,2,3,4,5,6];
let result = filter(item=>item%3==0);
alert(result);
代码语言:javascript复制let arr = [
{title:'a',price:10002},
{title:'b',price:999},
{title:'c',price:789},
{title:'d',price:10090},
{title:'e',price:11122},
];
let result=arr.filter(json=>json.price>=10000);
console.log(result);
forEach
代码语言:javascript复制let arr = [1,2,3];
arr.forEach((item,index)=。{
alert(index ':' item);
});
剩余参数与分布参数、默认参数
剩余参数
ES6去除了arguments对象,因此无法通过它读取未声明的参数。
不过,使用剩余参数(rest arguments)语法,也能表示你期待给函数传入 可变 数量 的参数。 剩余参数的语法形式是三个点后面跟一个标识符。 使用 这种语法可以定义可能会传进来的更多参数,然后把它们收集到一个数组中。
代码语言:javascript复制function sum(num1,num2,...nums){
var result = num1 num2;
for(let i=0,len=nums.length;i<len;i ){
console.log(nums[i]);
result =nums[i];
}
}
var result = sum(1,2,3,4,5,6);
剩余参数会保存在nums数组中。与原来的arguments不同,剩余参数都保存在Array的一个实例中。所以,可以使用任何数组方法 来操作它们。
分布参数
分布参数可以向函数中 传入一个数组,然后数组中的元素会映射到函数的每个参数上。 分布参数的语法形式与剩余参数的语法相同,就是在值的前面加三个点。 唯一的区别是分布参数在调用函数的时候使用,剩余参数在定义函数的时候使用。
代码语言:javascript复制var result = sum(...[1,2,3,4,5,6]);
默认参数
为参数指定默认值。如果调用函数时没有传入该参数,那么该参数就会使用默认值。 要为参数指定默认值,可以在参数名后面直接加上等于号和默认值。
代码语言:javascript复制function sum(num1,num2=0){
}
sum(5);
字符串
- 多两个新方法 startsWith //以…开头 endsWith //以…结尾
- 字符串模板
两个新方法
代码语言:javascript复制let str= 'http://abc.com';
if(str.startsWith('http://')){
}else if(){
}
代码语言:javascript复制let str = 'a.txt';
if(str.endsWith('.txt'){
alert('文本文件');
})
字符串模板 1、直接把东西塞到字符串里面 ${东西} 2、可以折行 反单引号`
代码语言:javascript复制let a=12;
let str = `a${a}c`;//str = a12c
# 字符串拼接
let title = '标题';
let content = '内容';
let str = '<div>
<h1>' title '</h1>
<p>' content '</p>
</div>';
#改写
let str2 = `<div>
<h1>${title}</h1>
<p>${content}</p>
</div>`;
Map
代码语言:javascript复制用map替代if-else/switch
const fn = ()=> {
console.log('find')
}
let handle = function(){}
const map = new Map();
const arr = [1,3,5,7,9];
map.set(arr,fn);
const getVal = (params) => {
for(let value of map.entries()){
if(value[0].includes(params)) {
handle = value[1]
}else {
console.log('not find')
}
}
}
let i = 9;
getVal(i);
handle()
ES6 的面向对象
新旧对比 1、class 关键字,构造器和类分开 2、class 中直接加方法
特点
- 继承
旧版
代码语言:javascript复制function User(name,pass){
this.name = name;
this.pass = pass;
}
User.prototype.showName = function() {
alert(this.name);
}
User.prototype.showPass = function() {
alert(this.pass);
}
var user = new User('blue','123');
user.showName();
user.showPass();
新版
代码语言:javascript复制class User{
constructor(name,pass){
this.name = name;
this.pass = pass;
}
showName() {
alert(this.name);
}
showPass() {
alert(this.pass);
}
}
var user = new User('blue','123');
user.showName();
user.showPass();
继承
代码语言:javascript复制class vipUser extends User{
constructor(name,pass,level){
super(name,pass); //super关键字,超类(父类)
this.level = level;
}
showLevel(){
alert(this.level);
}
}
var v1 = new vipUser('blue','123');
v1.showName();
v1.showPass();
v1.showLevel();
应用 React
- 组件化——class
- JSX (JSXbabelbrowser.js),JS扩展版本
class Test extends React.Component {
constructor(...args) {
super(...args);
}
render(){
return <span>123</span>;
}
}
window.onload = function() {
let oDiv = document.getElementById('div1');
ReactDOM.render(
<Test></Test>,
oDiv
);
};
JSON
- JSON对象 JSON.stringify; JSON.parse;
- JSON简写(名字一样;方法)
let json = {a:1,b:2};
let str = 'http://abc.com?data=' encodeURIComponent(JSON.stringify(json)); //stringify字符串化
json 标准写法 1、只能用双引号 2、所有的名字都必须用引号包起来
代码语言:javascript复制let str = '{"a":12,"b":5,"c":"abc"}';
let json = JSON.parse(str);
简写 1、名字与值一样的时候,可保留一个
代码语言:javascript复制let a =1;
let b =5;
let json = {a:a,c:b};//等价于let json = {a,c:b};
2、方法简写
代码语言:javascript复制let json = {
a:1,
show(){
alert(this.a);
}
}
json.show();
export/import
模块,或者称为“命名空间”或“包”,是组织javasript应用代码的重要方法。
每个模块都包含独立于其他模块的特定、独一无二的功能。
模块在其自己的顶级执行环境中运行,因而不会污染导入它的全局执行环境。默认情况下,模块中声明的所有变量、函数、类等都是该模块私有的。
对于应该向外部公开的成员,可以在前面加上export
关键字。例如:
// a-module.js 写模块
module MyModule {
//公开成员
export let myobject= {};
export function hello() {console.log('hello')}
//隐藏成员
function nihao(){
}
}
b.js导入
//只导入myobject
import myobject from MyModule;
console.log(myobject);
//导入所有公开成员
import * from MyModule;
//列出要导入的成员
import {myobject,hello} from MyModule;
简言之,模块就是一种组织相关功能的手段,并且其能保护全局作用于不受污染。
参考:
- https://stackoverflow.com/questions/48140375/javascript-es6-import-expects-exactly-one-argument
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/export