ES6语法、this指向

ES6语法

ES6语法新增的变量的定义
let 定义变量

特点:

1.let定义的变量,不会进行预解析

<script>
	 console.log(int1);   //  var 关键词定义的变量,可以预解析,结果 undefined
	 console.log(int2);   //  let 关键词定义的变量,不能徐解析,结果 报错
	 var int1 = 100;
	 let int2 = 100;
</script>

2.let 定义的变量,与forEach()中的变量类似 , 每次执行都会定义出一个新的,相互之间不影响的变量 , 尤其是在循环中,for,forEach,for...in,都最好使用let定义变量

<script>
    	// var 定义的是一个变量,后赋值会覆盖之前的数据
        // 最终i的数值是一个数值,是最终循环结束时,i的数值
        for(var i = 0 ; i <= oLis.length-1 ; i++){
            oLis[i].onclick = function(){
                console.log(i+1);
            }
        }
    
       // 与forEach 是 相同的赋值方式
       // 每次循环都建立一个独立的,相互不影响的 i 变量, 存储对应的数值
       // 每一次点击,不同的标签,调用的是不同的 i变量,输出的是不同的 存储数值
        for(let i = 0 ; i <= oLis.length-1 ; i++){
            oLis[i].onclick = function(){
                console.log(i+1);
            }
        }
</script>

3.let不能重复定义变量名称,一个变量名称只能定义一次

<script>
    // 使用 var 关键词 来定义变量
    // 变量名称可以重复
    var int = 100;
    var int = 200;
    console.log(int);

    // 使用 let 关键词 来定义变量
    // 变量名称不能重复
    // 只要是已经定义的,不管是var 还是 let 定义的,都不能重复
    // let int = 300;
    let int1 = 100;
    // let int1 = 200;
</script>

4.let 定义的变量,如果是定义在 { } 中,只能在 { } 中被执行被调用 , 在 { } 之外,是不能被调用执行的 , { } 包括 if switch for forEach for...in while function

<script>
    // 在for循环中,使用var 定义的循环变量
    for(var i = 0 ; i<= 10 ; i++){}
    // 在循环外可以调用循环变量
    console.log(i);

    // 在for循环中,使用let 定义的循环变量
    for(let j = 0 ; j<= 10 ; j++){}
    // 在循环外不能调用循环变量,会报错
    // console.log(j);
</script>

5.let 在不同 { } 中,是不同作用域中定义let变量 , 此时,变量的名称与 其他 { } 中的变量名称,或者{ }之外的变量名称,是可以重复

<script>
    // 在不同函数中,定义的let
    function fun1(){
        let str = '北京';
        return str;
    }
    console.log(fun1());

    function fun2(){
        let str = '上海';
        return str;
    }
    console.log(fun2());

    if(true){
        let int = 100;
        console.log(int);
    }

    if(true){
        let int = 200;
        console.log(int);
    }
</script>
const 定义变量

在JavaScript中往往,管const定义的变量,称为常量

特点:

1.const定义的变量,不能被重复赋值,数据已经定义,不能更改

<script>
    const strstr = 100;
    // 对const定义的变量,重复赋值,会报错
    // strstr = 200;//报错
    const ary = [100,200];
    arr[0] = 'a';
    arr[1] = 'b';
    console.log(ary);//['a','b']; 通过数组索引可以修改地址中存储的数值 不会修改地址
    ary = ['a','b'];//报错 地址被修改
</script>

2.const定义的变量名称,也不能重复

<script>
    const strstr = 100;
    // 对const定义的变量,重复赋值,会报错
    // const strstr = ''//报错
</script>

3.const定义在{}中,不能在{}外调用

<script>
    if(true){
        const sss = 'sss';
        console.log(sss);
    }
    // console.log(sss);//报错

</script>

4.一般使用 const 定义 对象,数组,函数,引用数据类型

const中存储的是引用数据类型的地址,只要地址不改变,可以改变数组,对象中的单元存储的数据

<script>
    const arr = [1,2,3,4,5,6];
    // 给数组中第1个单元,修改存储的数据
    // const arr 中存储的数组的地址是不改变的,可以执行的
    arr[0] = '北京';
    console.log(arr);//["北京",2,3,4,5,6]

    // 修改对象中,单元存储的数据,不是修改 obj中存储的内存地址,是可以执行的
    const obj = {name:'张三'};
    obj.name = '李四';
    console.log(obj);//{name:'李四'}
</script>

5.使用const关键字声明的变量必须赋初始值

箭头函数
箭头函数

所谓的箭头函数 是函数的另一种语法形式

配合 面向对象 和 构造函数

普通函数:const fun = function(){} 箭头函数:const fun = ()=>{}

如果函数只有一个参数,可以不写() 普通函数const fun = function(e){}箭头函数:const fun = e => {}

如果执行体中只有一行代码,可以不写{}普通函数const fun = function(e){}箭头函数:const fun = e=> console.log(e)

普通函数的this指向

1,声明式 — 指向的是window

<script>
     function fun1(){
         console.log(this);
     }
     fun1();//window
</script>

2,匿名函数/赋值式 — 指向的是window

<script>
     const fun2 = function(){
         console.log(this);
     }
     fun2();//window
</script>

3,定义在对象中的函数 — 指向的是对象

<script>
    const obj = { 
        fun3 : function(){
            console.log(this);
        }
    }
    obj.fun3();//Object
</script>

4,绑定的事件处理函数 — 指向的是绑定事件处理函数的标签

<div></div>
<script>
     const oDiv = document.querySelector('div');
     	oDiv.onclick = function(){
    	console.log(this);//<div></div>
     }
</script>
箭头函数中的this指向

在箭头函数中,this指向,父级程序的this指向

如果父级程序有this指向,那么箭头函数指向的就是父级程序的this

如果父级程序没有this指向,那么指向的就是window

<div></div>
<script>
     const oDiv = document.querySelector('div');
     oDiv.addEventListener('click' , ()=>{
            console.log(this);//window
      })
</script>

forEach()中 函数的this指向,就是window

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>
<script>
    // 对li进行操作
    const oLis = document.querySelectorAll('li');
    oLis.forEach(function(item,key){
        console.log(this);  // 输出的是forEach的函数的this指向 window
        // 箭头函数的this,是父级程序,forEach()的this,是window
        item.addEventListener('click' , ()=>{
            console.log(this);//window
        })
    })
</script>
<script>
     const obj = {
         // 普通函数,this指向对象
         fun1 : function(){console.log(this)},
         // 箭头函数this指向是,父级程序
         // 父级程序是对象
         // 只有函数有this,obj对象没有this
         // 父级程序没有this,指向的是window
         fun2 : ()=>{console.log(this)},

         // fun3是一个普通函数,this指向的是obj对象
         fun3 : function(){
             // fun4,是一个箭头函数,this指向的是父级程序的this指向
             // 父级程序是fun3,fun3的this是对象,fun4箭头函数的this也是对象
             const fun4 = ()=>{console.log(this)};
             fun4();
         }
     }
     obj.fun1();//Object
     obj.fun2();//window
     obj.fun3();//Object
</script>
改变this指向

重点:箭头函数,不能改变this指向,只有普通function函数,能改变this指向

改变this指向的方法

1, call()方法

语法: 函数.call(参数1,其他参数…可以是多个或者没有 )

作用: 调用并且执行函数,同时,将函数的this指向,定义为指定的内容(参数1)

参数1,是改变的this的指向

其他参数,是原始函数的实参,原始函数有几个形参,此时就要对应的输入几个实参,没有形参,就没有实参

2, apply()方法

**语法: **函数.apply(参数1,参数2) 只有两个参数

参数1:改变的this的指向内容

参数2:原始函数的实参,必须是一个数组的形式,将实参定义成数组的单元

其他用法和作用于 .call是相同的

3, bind()方法

语法: const 变量 = 函数.bind(参数1);

call apply 都是立即执行函数

bind 不是立即执行函数

生成一个新的函数,这个新的函数是改变this指向之后的新的函数

参数1,定义的要改变的的this指向

其他参数,一般不定义,是使用函数原有的形参

<script>
    const obj1 = {
        name:'张三',
        age:18,
        sex:'男',
    }
    // 定义的带有参数的普通函数
    function fun3(name,age,sex){
        console.log(name,age,sex,this);
    }
    // 执行时,输出实参,此时this指向是window
    fun3('张三',18,'男');

    // 改变this指向 , call方法
    fun3.call(obj1,'李四',20,'女');

    // 改变this指向 , apply方法
    fun3.apply(obj1 , [ '王五' , 20 , '不知道' ])

    // bind方法,不是立即执行函数,而是定义生成一个新的函数
    // 新生成的函数,this指向是参数1
    // 新生成的函数,形参是原始函数fun3的形参
    const fun4 = fun3.bind(obj1);

    fun4('王二麻子' , 100 , '不详');
</script>
立即执行函数

语法:

(封装的函数)()

!封装的函数()

~封装的函数()

<script>
    ( function fun1(){console.log(123)} )()
    // 立即执行函数,并没有真正的定义真个函数
    // 没有办法正常的再次调用这个函数
    !function fun1(){console.log(123)}()
    ~function fun1(){console.log(123)}()
</script>
数组的解构语法
<script>
    // 数组的解构语法
    // 就是数组的另一种使用调用方法
    // 可以不通过 []语法,不通过索引下标,来调用使用数组中的数据
    // 用于将数组中的数据,一一对应的赋值给变量

    const arr = ['北京','上海','广州','重庆','天津'];
    // 之前使用数组的数据,必须通过[]语法和索引下标
    // let str1 = arr[0];
    // let str2 = arr[1];
    // let str3 = arr[2];
    // let str4 = arr[3];
    // let str5 = arr[4];

    // 将 arr 中的数据,调用出来,给 左侧内容进行一一对应的赋值
    let [str1,str2,str3,str4,str5] = arr;
    console.log(str1,str2,str3,str4,str5);

    // 结构多层的数组
    // 二维数组
    const arr2 = ['北京','上海',['a','b','c']];
    // s1对应北京,s2,对应上海,s3,对应['a','b','c']
    // let [s1,s2,s3] = arr2
    // 接续把 s3 对应的数组  ['a','b','c'] 解析
    // s1对应北京,s2对应上海,[]对应['a','b','c']
    // s3对应a s4对应b s5对应c
    let [s1,s2,[s3,s4,s5]] = arr2
    console.log(s1,s2,s3,s4,s5);
</script>   
对象的解构
<script>
    // 对象的解构
    // 之前对象数据的调用,通过.语法或者[]语法,配合属性来调用操作数据
    // 现在可以使用解构语法来调用操作数据

    const obj = {
        name:'张三',
        age:18,
        sex:'男',
        addr:'北京',
        phone:123456,
    }

    // 之前调用数据
    // let str1 = obj.name;
    // 解构语法
    // 将对象中,属性是name的属性值,调用,赋值给name变量名称
    // {}中定义的属性,一定是对象中具有的属性
    // 变量名称,就是name也就是属性名称
    // let {name} = obj;
    // console.log(name);

    // 解构语法之定义其他名称
    // 在对象obj中,找name属性,将对应的数值数据,赋值给变量别名userName
    // 通过userName来调用使用数据
    // 只能一次解构一个数据,不能一次性的做一一对应的赋值
    // let {phone:userName} = obj;
    // console.log(userName);

    // 多级对象的解构
    const obj2 = {
        name1:{
            name2:'张三'
        }
    }

    // let {name1 : {name2}} = obj2;
    let {name1 : {name2:userName}} = obj2;
    console.log(userName); 
    // 只有name2解构对应张三,name1没有内容
    // console.log(name1); 
    // 如果只是 let {name1} = obj2
    // name1存储的是 对象 {name2:'张三'}
</script>
展开运算符
<script>
    // 展开运算符
    // ...数组
    // 将数组中的数据,展开来使用
    // 在函数的实参中使用

    // 有多个形参
    function fun(num1,num2,num3,num4,num5){
        console.log(num1,num2,num3,num4,num5)
    }
    // 执行时就要输入多个实参
    fun(100,200,300,400,500);

    // 现在有一个数组,存储多个数据
    const arr = [1,2,3,4,5];
    fun(arr[0],arr[1],arr[2],arr[3],arr[4]);
    // 展开运算符,将数组中的数据展开使用
    // 将arr中的数据,展开,对形参进行一一对应的赋值
    // 通过数组,给多个形参赋值更简单
    fun(...arr);

</script>
合并运算符
<script>
    // 合并运算符
    // ...
    // 在函数的形参中使用
    // 作用:将赋值的所有的实参,都是以数组的形式,存储在形参中

    // 只有一个形参,形参只能存储一个实参 
    function fun(arr){
        console.log(arr);
    }
    // 即时输入多个参数,只有一个形参,也只能存储第一个实参
    fun('a','b','c','d');


    // 合并运算符
    // 不管实参有几个,都以数组的形式,存储在形参中
    function fun1(...arr){
        console.log(arr);
        // 调用存储在形参arr中的实参,必须用过[]语法,索引下标
        // 或者 循环遍历 获取
    }
    // 输入的所有的实参,都会以数组的数据的形式,存储在形参arr中
    fun1('a','b','c','d','e',1,2,3,4,5);

    // 在 普通函数中,JavaScript定义了一个专门的变量,叫 arguments
    // 如果你没有定义形参,所有的实参都会以数组的形式存储在这个变量中
    // 作用于合并运算符相同
    // 但是 箭头函数中 没有 arguments 这个变量
    // 必须使用 ...形参 合并运算符的形式 来存储实参

    // 没有形参,JavaScript自动在arguments中,以数组的形式存储实参
    function fun3(){
        console.log(arguments);
    }

    fun3(1,2,3,4,5,6,7);
    // 箭头函数没有arguments,会报错
    // 只能使用 合并运算符 ...形参
    // const fun4 = ()=>{
    //     console.log(arguments);
    // }

    // fun4(1,2,3,4,5);

    const fun5 = (...arr)=>{
        console.log(arr);
    }

    fun5(1,2,3,4,5);
</script>
合并对象assign
<script>
    let a = {a : 'hell'};
    let b = {b : 'js'};
    let c = Object.assign(a,b);
    console.log(c);
</script>
class

ES5和ES6语法的对比

封装class类

与ES5语法区别,封装的是class关键词,不会被预解析

<script>
    // 1,ES5语法
    function Fun1(name,age){
        this.name  = name;
        this.age = age;
    }
    Fun1.prototype.f1 = function(){
        console.log(this.name , this.age);
    }
    const obj1 = new Fun1('张三',18);
    console.log(obj1);
</script>
<script>
    // 2,ES6语法  class
    class Fun2{
        //构造器,专门接收封装类时的参数和给实例化对象定义属性和属性值
        constructor(name,age){
            this.name = name;
            this.age = age;
        }

        f2(){
            console.log(this.name , this.age);
        }
    }
    const obj2 = new Fun2('李四',20);
    console.log(obj2);
</script>
模块化
//a.js
//导出一个变量、一个函数、一个类
{
	export let A = 123;
	export function test(){
		console.log('test');
	}
	export class Hello{
		test(){
			console.log('class');
		}
	}
}
//b.js
{
	import {A,test,Hello} from './a'
	console.log(A,test,hello)
}

另一种书写方式

//a.js
//导出一个变量、一个函数、一个类
{
	export let A = 123;
	export function test(){
		console.log('test');
	}
	export class Hello{
		test(){
			console.log('class');
		}
	}
}
//b.js
{
	import {A} from './a'
	console.log(A)//123
}

另一种书写方式

//a.js
//导出一个变量、一个函数、一个类
{
	export let A = 123;
	export function test(){
		console.log('test');
	}
	export class Hello{
		test(){
			console.log('class');
		}
	}
}
//b.js
{
	import * as abc from './a'
	console.log(abc.A,abc.test)//123
}

另一种书写方式

//a.js
//导出一个变量、一个函数、一个类
{
	let A = 123;
	function test(){
		console.log('test');
	}
	class Hello{
		test(){
			console.log('class');
		}
	}
	export default{
		A,
		test,
		Hello
	}
}
//b.js
{
	import abc from './a'
	console.log(abc.A)//123
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值