zoukankan      html  css  js  c++  java
  • 0xx_ES6


    第0章 先谈ES5继承

    继承:多个子类对象可以共用父类对象的成员属性和成员方法(代码重用--重复使用);

    0.1 原型链继承

    核心原理:B.prototype = new A();

    能够继承A构造函数以及原型链上的所有成员。

    	//定义父类构造函数
    	function A(){
    		this.age = 10;
    	}
    	A.prototype.say = function(){
    		console.log(100);
    	}
    	//定义子类构造函数
    	function B(){
    
    	}
    	//设置子类构造函数的原型对象 = 父类构造函数的实例对象
    	B.prototype = new A();
    	
    	var b = new B();
    	console.log(b.age);
    	b.say();
    

    缺点:子对象自身的constructor属性丢失了, 变成了父类构造函数

    0.2 冒充继承

    实现方式:在子类构造函数中,调用父类构造函数的(call, apply, bind)方法,使用子类构造函数的this去冒充父类构造函数的this。

    父类.call(子类的对象, 其他参数); //意思是让子类的对象,去代替父类中的this。

    	//父类构造函数
    	function A(){
    		this.age = 10;
    		this.say = function(){
    			console.log(100);
    		}
    	}
    	//子类构造函数
    	function B(){
          	//将B中的this,传给A,使A中的this指向B的this。
    		A.call(this);
    	}
    
    	var b = new B();
    	console.log(b.age);
    	b.say();
    

    缺点:这种实现继承的方式,是不能继承父类原型对象上的成员

    	function A(){
    		this.age = 10;
    	}
    	A.prototype.say = function(){
    		console.log(100);
    	}
    	function B(){
    		A.call(this);
    	}
    	var b = new B();
    	console.log(b.age);
    	b.say();//报错
    

    0.3 Object.create()继承

    Object.create()是IE9才开始支持的。

    var 新对象 = Object.create(原型对象); 该方法就是用于创建新对象并指定原型对象的。所以就可以直接使用create方法实现继承。

    特点:父类构造函数以及其原型链上的成员都能继承。

    适合场景:新的对象 没有直接对应的一个自定义构造函数

    不指定原型对象(不继承),参数可以为null。 即 var obj = Object.create(null);

    	function A(){
    		this.age = 10;
    	}
    	A.prototype.say = function(){
    		console.log(100);
    	}
    
    	var obj = Object.create(new A());
    
    	console.log(obj.age);
    	obj.say();
    
    	//或者
    /*
    	var obj = Object.create({
    		age:10,
    		say:function(){
    			console.log(100);
    		}
    	});
    	console.log(obj.age);
    	obj.say();
    */
    
    

    第1章 常量

    ES5没有定义声明常量的方式,ES6标准中引入了新的关键字const来定义常量。

    <script>
    	const PI = 3.14;
    	console.log(PI);
    </script>
    

    常量必须给初始值; 常量不能在同一作用域内重新定义或赋值;

    <script>
      	//常量不能在同一作用域中重新定义
    	const PI = 3.14;
    	const PI = 3.1415; //报错
    </script>
    <script>
      	//常量不能在同一作用域中重新赋值
    	const PI = 3.14;
    	PI = 3.1415; //报错
    </script>
    <script>
      	//不同作用域中可以声明同名常量
    	const PI = 3.14;
    	console.log(PI);//3.14
    	function fn(){
          	const PI = 3.1415;
          	console.log(PI);
    	}
    	fn();//3.1415
    </script>
    

    第2章 块级作用域

    2.1 块级作用域

    JS中作用域有:全局作用域、函数作用域。

    ES6中新增了块级作用域。
    块作用域由 { } 包括,if语句和for语句里面的{ }就属于块作用域。(不包括函数)

    //注意 块级作用域中,使用var声明的变量是全局变量
    {
    	var a = 1;
    	console.log(a);//1
    }
    console.log(a);//1
    
    if(true){
    	var b = 2;
    	console.log(b);//2
    }
    console.log(b);//2
    

    2.2、let关键字声明块级变量

    ES6中增加了let关键字声明变量,声明的变量只在当前代码块中生效(块级作用域)。

    <script>
        if(true){
            let i=0;
            console.log(i);
        }
      console.log(i);//报错
    </script>
    <script>
        for(let i=0; i<=6; ++i){
            console.log(i);
        }
        console.log(i);//报错
    </script>
    
    

    使用let声明的变量可以重新赋值,但是不能在同一作用域内重新声明

    <script>
      	// let声明的变量可以重新赋值
        {
            let a = 1;
          	console.log(a);
          	a = 2;
         	console.log(a);;
        }
    </script>
    
    <script>
      // let声明的变量不能在同一作用域重新声明,直接报错 预解析错误
      {
      	let a = 1;
      	console.log(a);
      	let a = 2;
      	console.log(a);
    }
    </script>
    

    2.3、let变量没有变量提升

    {
     	console.log(i);//报错
    	let i = 8;
    }
    

    2.4、应用:let块级变量解决i丢失的问题

    var arr = [3,4,5,6,7];
    
    for(let i=0; i<arr.length; i++){
    	// (function(i){
    		setTimeout(function(){
    			console.log(i);
    			//console.log(arr[i]);
    		}, 1000);
    	// })(i);
    }
    

    第3章 字符串模板(模板字面量)

    js中单双引号字符串,均不解析变量,需要使用+号将变量拼接在字符串中。

    ES6中提供了字符串模板语法,允许使用反引号(倒引号) `` 来创建字符串,里面可以包含${变量名}形式的变量占位符。 其中的变量会被解析。

    反引号字符串还可以换行

    //生成一个随机数
    var num=Math.random();
    
    //将这个数字输出到console
    console.log('your num is ' + num);
    console.log(`your num is ${num}`);
    
    var str = `hello
    欢迎来到黑马大讲堂`;
    console.log(str);
    

    第4章 函数

    4.1 参数默认值

    ES5中定义函数时,不能指定参数的默认值。

    ES6中定义函数时,可以指定参数的默认值。

    //ES5中,只能变相实现参数默认值(函数内部加判断处理)
    function f1(username){
    	//传统的指定默认参数的方式
    	var username = username || 'zhangsan';
    	console.log('Hello ' + username);
    }
    f1();//Hello zhangsan
    f1('lisi');//Hello lisi
    
    
    //ES6中,直接给形参设置默认值
    function f2(username='zhangsan'){
    	console.log(`Hello ${username}`);
    	//console.log('Hello ' + username);
    }
    
    f2();//Hello zhangsan
    f2('lisi');//Hello lisi
    

    4.2 展开运算符(拆包)

    ES6新增了展开运算符(用三个连续的点 (...) 表示),能够将数组和字符串字面量展开为多个元素

    //展开数组
    var arr = [1, 2, 3];
    console.log(arr); // [1, 2, 3]
    console.log(...arr); // 1 2 3
    //展开字符串
    var str = "hello";
    console.log(str);
    console.log(...str);
    

    应用:拓展参数

    它允许传递数组或者类数组直接做为函数的参数。

    //函数本来接收三个单独的参数
    function f3(x,y,z){
    	console.log(x,y,z);
    }
    
    //ES6中,我们可以将一个数组以拓展参数的形式传递,它能很好地映射到每个单独的参数
    var arr=[3,4,5];
    f3(...arr);//输出:3 4 5 
    
    //ES5中,如果需要传递数组当参数,我们需要使用函数的apply方法
    f3.apply(null,arr);//输出:3 4 5 
    

    4.3 不定参数(可变参数/剩余参数)

    不定参数是指,在函数中使用 命名参数 同时接收 不定数量 的 未命名参数,需要使用三个连续的点 (...) 。

    这是一种语法糖(在原语法上的简化用法),ES5通过函数内部的arguments对象来达到类似效果。

    不定参数的格式:

    //不定参数 将多个实参放在一个数组变量中
    //  ...x  三个点是固定格式,x是形参变量名
    function f1(...x){
    	console.log(x);
    }
    f1(3,4,5); //[3,4,5]
    
    function f2(m, n, ...x){
      	console.log(m, n, x);
    }
    f2(2,3,4,5,6); // m=2  n=3  x=[4,5,6]
    

    第5章 解构(拆包)

    在ES6中,可以使用解构从数组和对象提取值并赋值给独特的变量,即将数组或对象中的值,拆成一个一个变量。

    解构:自动解析数组或对象中的值,并赋值给指定的变量。

    5.1 数组解构

    将数组中的值,取出并赋值给多个变量

    	var arr = [3,4,5];
    	var [a, b, c] = arr;
    	console.log(a, b, c);
    	
    	//还可以忽略值 需要使用,占位
    	var arr = [3,4,5];
    	var [a,, c] = arr;
    	console.log(a, c);
    
    	//函数返回值为数组,进行解构
    	function f5(){
    		return [1,2,3];
    	}
    	var [a, b, c] = f5();
    	console.log(a, b, c);
    

    5.2 对象解构

    将对象中的成员值,取出并赋值给多个变量(变量名与对象成员名一致)

    var person = {
        "nickname": "老三",
        "age": 30,
        "sex": "男"
    };
    //解构时 {}中的变量名,不能加引号
    var {nickname, age, sex} = person;
    console.log(nickname, age, sex);
    //可以忽略值  直接忽略 不需要占位
    var {nickname, sex} = person;
    console.log(nickname, sex);
    

    5.3 函数参数默认值与解构

    5.3.1 函数参数与解构

    函数参数使用解构数组或解构对象形式

    //1.函数形参,使用解构数组形式,调用函数时需要传递数组实参
    function f1([x,y,z]){
      	console.log(x,y,z);
    }
    var arr = [1,2,3];
    f1(arr);
    
    //相当于
    /*
    function f1(a){
      	var [x,y,z] = a;
      	console.log(x,y,z);
    }
    var arr = [1,2,3];
    f1(arr);
    */
    
    //2.函数形参,使用解构对象形式,调用函数时需要传递对象实参
    function f2({nickname,age,sex}){
      	//变量名与对象成员名一致
      	console.log(nickname,age,sex);
    }
    var obj = {"nickname":"zhangsan", "age":40, "sex":"男"};
    f2(obj);
    
    //相当于
    /*
    function f1(a){
      	var {nickname, age, sex} = a;
      	console.log(nickname,age,sex);
    }
    var obj = {"nickname":"zhangsan", "age":40, "sex":"男"};
    f2(obj);
    */
    

    5.3.2 默认值与解构数组

    函数参数使用解构数组 并设置默认值

    <script>
    //1.函数参数使用解构数组,调用函数不传参数会报错
    function fn([x, y, z]){
      	console.log(x, y, z);
    }
    fn(); //会报错
    </script>
    
    <script>
    //2.函数参数使用解构数组,对整个数组设置默认值为空数组
    function f1([x, y, z] = []){
      	console.log(x, y, z);
    }
    f1(); //不报错  x y z 都是 undefined
    
    //3.函数参数使用解构数组,对整个数组设置默认值,数组中每个变量对应一个默认值
    function f2([x, y, z] = [1,2,3]){
      	console.log(x, y, z);
    }
    f2(); //不报错  x=1 y=2 z=3
    f2([4,5,6]); // x=4 y=5 z=6
    
    
    //4.函数参数使用解构数组,对整个数组设置默认值为空数组, 在解构数组中对每个变量设置一个默认值
    function f3([x=1, y=2, z=3]=[]){
      	console.log(x, y, z);
    }
    f3(); //不报错  x=1 y=2 z=3
    f3([4,5,6]); // x=4 y=5 z=6
    </script>
    

    5.3.3 默认值与解构对象

    函数参数使用解构对象 并设置默认值

    <script>
    //1.函数参数使用解构对象,调用函数不传参数会报错
    function fn({x, y, z}){
      	console.log(x, y, z);
    }
    fn(); //会报错
    </script>
    
    <script>
    //2.函数参数使用解构对象,对整个对象设置默认值为空对象
    function f1({x, y, z} = {}){
      	console.log(x, y, z);
    }
    f1(); //不报错  x y z 都是 undefined
    
    //3.函数参数使用解构对象,对整个对象设置默认值,对象中每个变量对应一个默认值
    function f2({x, y, z} = {"x":1,"y":2,"z":3}){
      	console.log(x, y, z);
    }
    f2(); //不报错  x=1 y=2 z=3
    f2({"x":4,"y":5,"z":6}); // x=4 y=5 z=6
    
    
    //4.函数参数使用解构对象,对整个对象设置默认值为空对象, 在解构对象中对每个变量设置一个默认值
    function f3({x=1, y=2, z=3}={}){
      	console.log(x, y, z);
    }
    f3(); //不报错  x=1 y=2 z=3
    f3({"x":4,"y":5,"z":6}); // x=4 y=5 z=6
    </script>
    

    第6章 简化的(增强的)对象字面量

    ES5中的对象字面量

    var person = {
        "nickname": "老三",
        "age": 30,
        "sex": "男",
        "say":function(){
              return "hello";
        }
    };
    

    6.1 成员属性

    //如果成员属性值,是放在变量中的值, 且属性名称与变量名称一致
    var nickname = "老三";
    var age = 30;
    var sex = "男";
    // 预期 {"nickname":"老三", "age":30, "sex":"男"}
    //对象字面量可简写如下
    var person = {
        nickname,
        age,
        sex
    };
    console.log(person);
    

    6.2 成员方法

    成员方法 可省略 function 关键字

    // 预期 {"nickname":"老三", "age":30, "sex":"男", "say":function(){return "hello";}}
    var person = {
        "nickname":"老三",
        "age":30,
      	"sex":"男",
     	say(){
          return "hello";
     	}
    };
    console.log(person);
    console.log(person.say());//hello
    

    6.3 原型对象

    可以在对象字面量里面定义原型

    var person = {
     	say(){
          return "hello";
     	}
    };
    var coder = {
      	__proto__:person,
      	coding(){
          	return "I'm coding";
      	}
    };
    console.log( coder.say() );
    console.log( coder.coding() );
    

    第7章 for of值遍历

    ES6新增了for...of循环语法。

    //遍历数组
    var team = ["师父", "大师兄", "二师兄", "沙师弟", "小白龙"];
    for(var v of team){
      	console.log(v);
    }
    //也可以遍历字符串
    var str = "zhangsan";
    for(var v of str){
      	console.log(v);
    }
    //for of不能遍历对象{} 
    var person = {"nickname":"老三", "age":30, "sex":"男"};
    for(var v of person){	//报错
      	console.log(v);
    }
    

    第8章 Symbol数据类型

    ES5数据类型:6种: string number boolean null undefined object

    ES6新增了一种数据类型:Symbol,表示独一无二的值,Symbol最大的用途是用来定义对象的唯一属性名。

    Symbol值通过Symbol函数生成。

    var symbol1 = Symbol();
    
    var symbol2 = Symbol("Alice");
    
    console.log(symbol1, symbol2) // 输出:Symbol() Symbol(Alice)
    

    typeof运算符用于Symbol类型值,返回symbol。

    console.log(typeof Symbol("Alice")) // 输出:symbol
    

    Symbol类型的值是一个独一无二的值,Symbol函数的参数只是表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的。

    console.log(Symbol() == Symbol()); // 输出:false
    
    console.log(Symbol("Alice") == Symbol("Alice")); // 输出:false
    
    

    应用:作为对象属性名的Symbol

    var attr_name = Symbol();
    var obj = {
    	[attr_name]: "Alice"
    };
    console.log(obj[attr_name]);
    
    var obj = {
      	[Symbol()]:"Alice"
    };
    console.log(obj);
    

    注:Symbol值作为对象属性名时,不能用点运算符。由于点运算符后面总是字符串,所以不会读取attr_name作为标识名所指代的那个值。

    使用[]方括号,里面的attr_name不带引号,表示attr_name是一个变量.

    第9章 类和对象

    1、类的定义

    ES6中添加了对类的支持,引入了class关键字

    ES6中提供的类实际上只是JS原型模式的包装。现在提供class支持后,对象的创建、继承更加直观。

    class类中,可以包含 构造方法、实例方法、静态方法。

    //类的定义
    class A {
    	//ES6中的构造方法(类的属性,定义在构造方法中)
        constructor(name) {
            this.name = name;
            this.age = 30;
        }
        //实例方法
        say() {
            console.log('我是A中的实例方法say,我的名字是 '+this.name);
        }
      	//静态方法(静态方法与实例方法 同名互不影响)
     	static say(){
          	console.log("我是A中的静态方法say");
     	}
    }
    
    //直接调用静态方法
    A.say();
    
    //实例化类 调用实例方法
    var a = new A('Tom');
    a.say();
    
    //类也有原型对象
    console.log(A.prototype);
    console.log(a.__proto__)
    

    注意

    1.class类中不能直接定义属性,只能定义方法,方法之间不需要也不能使用逗号隔开

    2.类只能先定义,再使用,没有提升效果。

    3.静态方法只能通过类名直接调用,实例方法只能将实例化成对象后调用。

    2、类的继承

    注:父类有构造函数,子类构造函数中,需要调用super() 实现父类的构造函数,否则报错。

    //类的继承
    //父类A
    class A {
    	//ES6中的构造方法
        constructor(name) {
            this.name = name;
            this.age = 30;
        }
        //实例方法
        say() {
            console.log('我是A中的实例方法say,我的名字是 '+this.name);
        }
      	//静态方法
     	static say(){
          	console.log("我是A中的静态方法say");
     	}
    }
    
    //子类B
    class B extends A {
      	//构造方法
        constructor(name) {
        	//使用函数形式的super(), 直接调用父类构造方法
          	//只要子类写了构造方法,就必须调用super(),且必须在使用this之前
            super(name);
        }
      	//实例方法
      	//子类方法 会覆盖父类同名方法
        say() {
          	//子类方法中,可以使用super.方法() 调用父类的非构造方法
          	//当前方法是实例方法,则调用父类的实例方法
          	//当前方法是静态方法,则调用父类的静态方法
          	//super.say(); 
            console.log('我是B中的实例方法say,我的名字是 '+this.name);
        }
      	
        static coding() {
            console.log('我是B中的静态方法coding');
        }
      	
    }
    //调用静态方法
    B.say(); //A的静态方法
    B.coding();//B自己的静态方法
    
    //调用实例方法
    var b = new B('Lucy');
    b.say();//B中的实例方法say  //如果B中没有,才调用A的实例方法say
    b.coding();//报错,B和A中都没有实例方法coding  (只有静态方法)
    

    第10章 箭头函数

    ES6可以使用“箭头”(=>)定义函数,注意是函数,不要使用这种方式定义类(构造器)。

    10.1 语法

    1.具有一个参数并直接返回的函数

    var f1 = a=>a;
    //相当于  var f1 = function(a){ return a;};
    console.log(f1('hello'));//'hello'
    

    2.没有参数的需要用在箭头前加上小括号

    var f2 = () => '来了老弟';
    console.log(f2());
    

    3.多个参数需要用到小括号,参数间逗号间隔

    var f3 = (a, b) => a+b;
    console.log(f3(3,4));//7
    

    4.函数体多条语句需要用到大括号

    var f4 = (a, b) => {
      	console.log('来了老弟');
      	return a+b;
    }
    console.log(f4(5,6));//11
    

    5.返回对象时需要用小括号包起来,因为大括号被占用解释为代码块

    var f5 = () => {
      	return ({"name":"老弟", "age":40});
    }
    
    //var f5 = () => ({"name":"老弟", "age":40});
    console.log(f5());
    

    6.直接作为事件处理函数

    <input type="button" value="点击" id="btn">
    <script>
    	document.getElementById('btn').onclick = evt=>{
          	console.log(evt);//evt 事件对象
    	}
    </script>
    

    7.赋值为对象的方法

    var obj = {};
    obj.say = ()=>{return "hello,我是obj的say方法";}
    console.log(obj.say());
    

    8.作为回调函数

    var f6 = (f)=>{
        console.log(f(100));
    };
    // f6(a=>a);
    var f7 = a=>a;
    f6(f7);
    

    10.2 注意点

    1. typeof 判断箭头函数 结果为function
    var f1 = a=>a;
    console.log(typeof f1);//'function'
    
    1. instanceof判断是否Function的实例,结果为true
    var f1 = a=>a;
    console.log(f1 instanceof Function);//true
    
    1. 箭头函数不绑定this, 内外this指向固定不变

    这个很有用,再不用写me,self,_this了,或者bind。

    var obj = {
      	say:function(){
          	//非箭头函数
          	var _this = this;
          	var f1 = function(){
          		console.log(_this);//obj
    			console.log(this);//window
            };
          	f1();
          	//箭头函数
            var f2 = ()=>{
    			console.log(this);
            };
          	f2();
      	}
    };
    obj.say();
    
    1. 箭头函数不能做构造函数,不能用new实例化,也没有prototype属性
    var Person = ()=>{};
    console.log(Person.prototype);//undefined
    var p = new Person();//报错
    
    1. 不能使用arguments
    var f1 = ()=>{
    	console.log(arguments);
    };
    f1(); //报错
    

    6.箭头函数也支持默认参数、剩余参数、解构

    var f1 = (x=1,y)=>{
      	console.log(x, y); //3 4
    };
    f1(3,4);
    var f2 = (...x)=>{
      	console.log(x); //[3,4]
    };
    f2(3,4);
    var f3 = ([x,y]=[])=>{
      	console.log(x, y); //3 4
    };
    f3([3,4]);
    
  • 相关阅读:
    数据不是搜集起来的,是沉淀下来的,跟脚印一样,脚印不是修路的人搜集起来的,只要有了路就一定有脚印,不可能说修一条路不留下脚印,世界上没有这样的路
    VC6.0编译的DLL文件能否反编译知道里面的代码?
    Why does the PDB format change every release?
    mysql_query与 mysql_real_query区别
    如何把Backtrack 5安装到U盘/Backtrack 4安装方法
    FreeBSD:像Linux下一样使用vim
    栈的出栈序列个数
    npm outdated -g --depth=0
    npm Updating packages downloaded from the registry
    TypeScript安装
  • 原文地址:https://www.cnblogs.com/xeclass/p/12654387.html
Copyright © 2011-2022 走看看