let
i 和 a 都能取到 说明js中用var 在for中声明的变量可以在外部访问
console.log(i);
for(var i = 0 ; i < 10;i++){
var a = i
}
console.log(i);
console.log(a);
在 js/es6 中使用let 在for中声明的变量无法在外部访问
for(let i = 0 ; i < 10 ; i++){
vat a = i
}
console.log(i);
console.log(a);
let声明的变量名不能重复,而且必须先申明在使用,换句话说 let 没有变量的提升和变量的污染
var a = 0;
let a = 1;
console.log(a)
块级作用域 相当于 局部作用域
在 js 中只有函数才能创造一个 局部作用域
但是在es 中只要是个{}他就是局部作用域(块级作用域)
{
var a = 0;
let b = 1;
}
console.log(a); // 0;
console.log(b); // 报错 找不到变量b
在 js 中 全局变量 何以在局部环境下使用 局部不能在全局下使用
在es6 中全局只能在全局使用 局部也只能在局部使用
而且 全局申明的变量跟局部申明的变量没有任何关系
变量名都可以一样
let 声明的变量只能在当前作用域使用
let a = 0;
{
console.log(a);
let a = 1;
console.log(a); //1
}
console.log(a);//0
const
const 关键字在es6中来声明静态常量
常量所有字母必须大写
const PI = 3.141592653589;
console.log(PI);
onsole.log(PI); // 报错 常量无法修改
const ABC;
console.log(ABC); // 常量在声明必须赋值
const 在作用特性上 跟let完全一样
var aa = 0;
let aaa = 1;
consloe.log(window)
var 声明的变量是写在了window 对象上是window的属性或方法
let 声明的变量跟window 完全没关系
let ppp = 123;
function fn1(p){
let a = p ;
console.log(a);
}
fn1(ppp);
let [a,b] = [1,2,3];
console.log(a)
console.log(b);
// console.log(c);
let arr = [1,2,3,4,5]
console.log(...arr);
var arr1 = [1,2,3,4,5];
var arr2 = arr1;
console.log(arr2);
let arr3 = [1,2,3,4,5]
let arr4 = [...srr3]
arr4.push(0)
console.log(arr4);
console.log(arr3);
解构赋值
正常的赋值
let x = 0;
let y = 1;
本质上就是一种 模式匹配
只要等号两边的模式相同 左边的变量
let [x,y] = [0,1]; //解构赋值;
let [a,[b1,b2],c] = [0,[1,2],3];
console.log(a);
console.log(b1);
console.log(b2);
console.log(c);
let [a,,b] = [1,2,3]
console.log(b); // 按位置匹配
//解构默认值
let [ a1 = 100] = [,1000]
console.log(a1);
let obj = {
names :'张三',
age : 18,
sex : '女',
data :[0,1,2,3,4]
say: function (){
console.log('你好我是张三');
}
}
es5
var name1 = obj.name;
var age1 = obj.age;
let {
names,
age,
say
} = obj;
console.log(names,age);
say();
console.log(say);
IE6 解构赋值 解构对象时变量名必须和属性名相同 但是顺序没有要求
以对象形式解构数组
let arr = [1,2,3,4,5]
let {
[0] : a,
[4] : b
}==arr
console.log(a);
console.log(b);
let obj = {
data: [0, 1, 2, 3, 4]
}
//当对象中含有数组是
let {
data,//以变量取出相对应键值对的值 变量名必须和属性名相同
data: arr, // 以属性名取出相对应键值对的值 并将值保存在变量arr中
data: [a, b, c, d, e]//将上一步中的arr彻底解构
} = obj
console.log(a);
console.log(b);
/console.log(c);
当对象中含有数组数组内又有对象
let obj = {
data:[{
age:1,
},{
name: 2,
}],
}
let {
data : [{age},{name}]
} = obj
console.log(age, name);
let str = 'Helloword';
let [a, b, c] = str
let {
[0] : d
} = str;
console.log(a,b,c,d);
解构赋值 解构字符串时 会将字符串当做一个数组来解构
函数的扩展
形参默认参数
function fn1(x){
var a = x || 10; // js中默认值
}
function fn2(x = 10){
// var a = x; // IE6中默认值
console.log(x);
}
// 形参默认值不是赋值 而是惰性传值
function fn3(x){
// var x = 0;
// let x = 0;
// console.log(x);
// 在IE6中不能用let或const什么与形参重复的 变量或常量
// 其实 不管是在 es6还是js中 形参跟变量名都经量不要重复
}
fn3(10);
箭头函数
+普通函数
命名函数
function fn1(a){
console.log(a)
}
字面量函数
var fn2 = function (a) {
console.log(a);
}
箭头函数
var fn3 = (a,b) => {
console.log(a, b);
}
fn3(10,11)
一个参数
一个参数可以省略括号
var fn4 = a => {
console.log(a);
}
没有参数
没有参数不可以省略括号
```
var fn5 = () => {
console.log(123);
}
有返回值的正常函数
function aa() {
return 123
}
箭头函数
let aa1 = () => 123; // 箭头函数
箭头函数中 如果只有一条return 语句
则可以省略大括号
如果这个箭头函数还有且只能一个形参
则小括号也可以省略
let aa1 = () => 123
普通
function b() {
return function (a) {
return a + 1
}
}
箭头函数
let b = () => a => a + 1;
let b1 = b()(1);
console.log(b1);
btn.onclick = function() {
console.log(this); // 标签
}
btn1.onclick = () =>{
console.log(this); // window
}
一般绑定事件函数的时候不要使用箭头函数
btn.onclick = function(){
setTimeout( function(){
console.log(this);
},3000);
}
btn1.onclick = function(){
setTimeout( () => {
console.log(this);
},3000)
}
btn.onclick = function(){
// btn1.onclick = function(){
// console.log(this);//btn1
// }
btn1.onclick = () =>{
console.log(this);//btn1
}
}
当内部函数使用箭头函数时不会改变外部函数的this指向
总结
普通函数 谁调用我 我的this就指向
箭头函数 我被定义 定义的环境中this指向谁 我的this就指向谁
```
let obj = {
say: function(){
console.log(this); // obj
},
eat:() => {
console.log(this); // window
}
}
obj.say();
obj.eat();
// 给对象定义方法是 不要使用 箭头函数、
function Data(){
this.say = function(){
console.log(this);
}
this.eat = () => {
console.log(this);
}
}
let d1 = new Data();
d1.say();
d1.eat();
- 字符串的扩展
模板字符串
``
console.log(
`)
在 模板字符串中 如果需要写一个 字符则要在
前面加上\
字符串的扩展的操作方法
let str = 'hellow'
1、includes()
查找指定字符串又返回值
能找到返回true
找不到返回false
console.log(str.includes('o')); //true
console.log(str.includes('a')); //false
2、startWith()
判断是否以 指定字符开始 返回值是布尔值
是返回true
不是返回 false
console.log(str.startsWith('h')); //true
console.log(str.startsWith('he'));//true
console.log(str.startsWith('hel'));//true
console.log(str.startsWith('helo'));//false
console.log(str.startsWith('o'));//false
console.log(str.startsWith('w'));//false
3、endsWith
判断是否以 指定字符开始 返回值是布尔值
是返回true
不是返回 false
4.repeat
将原字符串 重复复制指定次数 并将生成的新字符串返回
console.log(str.repeat('1'));
console.log(str.repeat('3'));
5、trim() 删除前后位空格
let str1 = 'a b c d e f';
console.log(str1);
console.log(str1.trim());
6. trimStart() //删除首位空格
7. trimEnd() //删除末尾空格
数组的括展
// ... 有序集合
let arr = [1,2,3,4,5]
console.log(...arr);//1,2,3,4,5
let [a,b,...c] = arr;
console.log(c);//[3,4,5]
function fn1(..arg){
console.log(arg);//[1,2,3,4,5,6]
}
fn1(1,2,3,4,5,6)
数组的深拷贝
let arr = [1,2,3,4,5,6]
+ 1、 for循环
let arr1 = [];
for(let i = 0 ;i < arr.length; i++){
arr1[i] = arr[i]
}
arr1.push(8)
console.log(arr);// [1, 2, 3, 4, 5, 6, 7]
console.log(arr2);// [1, 2, 3, 4, 5, 6, 7 ,8]
+ 2、concat
let arr2 = [].concat(arr)
arr2.push(8)
console.log(arr);// [1, 2, 3, 4, 5, 6, 7]
console.log(arr2);// [1, 2, 3, 4, 5, 6, 7 ,8]
+ 3、...
let arr3 = [...arr];
let [...arr4] = arr
arr4.push(9)
arr3.push(8);
console.log(arr);// [1, 2, 3, 4, 5, 6, 7]
console.log(arr3);// [1, 2, 3, 4, 5, 6, 7,8]
console.log(arr4);// [1, 2, 3, 4, 5, 6, 7,9]
- 数组的拼接
let arr = [1,2,3]
let arr1 = [4,5,6]
console.log([...arr,...arr1]); //[1,2,3,4,5,6]
数组的操作方法
数组的排序 .sort()
flat()
将多维数组展开成一维数组,通常用于数据处理
let arr = [[1,2,3],[4,5,6,[7,8,9]]]
console.log(arr.flat(1));// [1.2, 3, 4, 5, 6, Array(4), 1, 2]
console.log(arr.flat(2));//[1.2, 3, 4, 5, 6, 7, 8, 9, Array(3), 1, 2]
// 参数写几 就是展开几层
// 展开所有层参数写 Infinity
console.log(arr.flat(Infinity));//[1.2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
+forEach()
let arr = [1,2,3,4,5,6,7,8]
arr.forEach((val, i ,array) => {
console.log(val,i , array);
// 第一个参数 元素 value
// 第二个参数 索引值 index
// 第三个参数 原数组 array
// 参数名
});
对象的拓展
{//js
var obj = {
'name': '123',
'age': 123,
'say': function () {
console.log(234);
}
}
}
{//es6
var obj = {
name: '123',
age: 123,
say: function () {
console.log(234);
}
}
}
{
//ES6 中新写语法
let name = '123';
let age = '123';
let obj = {
name,
age,
sey(){
console.log(567)
return 12
}
}
console.log(obj.name)
console.log(obj.age)
console.log(obj.say)
}
面向对象
在es5 中没有一个类的概念 只有构造方式
在es6中js模拟了其他语言实现类的概念让对象可以有类来产生
es6虽然有了类 但是底层实现上还是以原型对象的拷贝来实例化对象
- 类
class Person{
//从底层上来讲在类里面定义的属性和方法都是之前的原型属性和方法
name = '张三 ';
age = '12';
say(){
console.log('hellow')
}
eat(){
console.log('这是父类的方法')
}
// 需要传参的属性写到构造函数里面
constructor(sex, job, money) {
this.sex = sex;;
this.job = job;
this.money = money;
}
}
类中构造函数里 写了多少个形参实例化的时候 就要按照顺序传入多少个实参
如果形参实参数不一样 没有传参属性值是undefined
let p1 = new Person("男", "程序猿")
console.log(p1.name);
console.log(p1.job);
console.log(p1.money);
- 继承
js 继承
原型继承
1、子类.prototype = new 父类
子类. prototype.constructor = 子类
2、子类.prototype = 父类.prototype;
子类.prototype.constructor = 子类
构造函数继承
3、call()
4、apply()
es6 继承
extends
class Man extends Person{
sex = '男' + Man.a;
// static (死达忒可) 修饰类属性和 类方法
// 只有类能使用的方法和属性 只能通过类名调用他
static a = '123';
static say() {
console.log('fasfdasdfsd');
}
fn1() {
this.eat();
console.log(this.sex);
}
eat() {
//super 将父类的方法在子类的方法调用
super.eat();
console.log('这是子类');
}
constructor(...arg) {
// super (苏坡) 如果放在子类的构造函数中
// 直接代表父类的构造函数
console.log(arg);
console.log(...arg);
// super(arg[0], arg[1], arg[2]);
super(...arg);
console.log(Man.a); // 123
}
names = super.name;
}
let m1 = new Man('女', '宝宝长', '18000')
m1.fn1()
在 类中 使用自身的属性或方法 用this来使用 this.属性 this.方法() 在 子类中 要使用父类的属性或方法 只能用 super super.方法 只有一种情况 列外 super 如果在子类的constructor中 代表着父类的constructor
class 定义类的关键字
继承 extends () 子类继承父类 (定义子类是 使用)
constructor 构造函数
static(死达忒可) 定义 类属性
super 代表父类公有属性 和 私有属性
function Person(){
this.money = 123123//公有
var money = 123123//私有
}
// es6中
class Person{
money = 123123;
constructor(){
this.money = 123123;//公有
var money = 123321; // 私有
}
// money =12341234;//公有
_money = 123123456;//私有属性
// set get 属性
set m1 (m){
this._money = m + 10000;
}
get m1(){
return this._money;
}
}
let d1 = new Person()
console.log( d1.m1); //123123456 给 私有属性一开始设置的那个值
d1.m1 = 5000;
console.log( d1.m1);
实例 私有
class Man {
_money = 0;
set m1(m){
this._money = m / 2
}
get m1(){
return this._money;
}
}
let b1 = new Man();
console.log(b1.m1);
b1.m1 = 3000;
console.log(b1.m1);
-
es6模块系统
模块化开发
本质生是为了解决 js 文件之间 相互引用
用来开发 大型的web应用将项目的各个功能 封装成一个一个js组件 开发时 分开去研发各个组件 最后 利用es6提供的模块系统 将各个组件导入到一个指定的住js组件中 这就是 模块化开发的思想 es6 模块系统 依托于两个关键字 (挨次帕特) export{} 导出 (应泡特) import{解构} from "路径" 导入