文档章节

ES6学习总结

wftt
 wftt
发布于 2018/04/27 17:59
字数 3235
阅读 163
收藏 0
ES6

一.题外话

使用了Visual Studio Code,简单叙述一下:

在官网下载好之后 ,打开编辑器后,点击左侧面板最后一个“扩展”,搜索 live-server并进行安装(实现效果:保存自动看到效果) ,然后是安装javascript code.

查看相关命令:ctrl + k,ctrl + s    从中可以搜索自己需要的命令

这样在写入代码保存后,右键Open With Live Server打开网页就可以查看对应效果了。

二.ES6的数组方法

1、forEach

var colors = ["red","blue","green"];

//ES5遍历数组的方法
// for(var i=0;i<colors.length;i++){
//     console.log(colors[i]);
// }

//ES6 forEach 
colors.forEach(function(color){
    console.log(color);
})

//括号内是迭代器函数,通过形参color来接收数组colors

2、map

/*
场景一:假定有一个数值数组A,将A数组中的值以双倍的形式放在B数组中.
*/

var numbers = [1,2,3];

var doubleNumbers = [];

//ES5 
//-----------------遍历numbers数组------------------
// for(var i=0;i<numbers.length;i++){
//     doubleNumbers.push(numbers[i]*2);
// }
// console.log(doubleNumbers);
//-----------------遍历doubleNumbers数组------------------
// for(var i=0;i<doubleNumbers.length;i++){
//     console.log(doubleNumbers[i]);
// }

//ES6 map
var doubled = numbers.map(function(num){
    return num*2;          //map返回一个数组,实现的效果等同于es5遍历numbers数组
})
console.log(doubled);
doubled.forEach(function(num){
    console.log(num);
})

3、find

/**
 * 场景一:假定有一个对象数组A,找到符合条件的对象
 */

var users = [
     {name:'Jill'},
     {name:'Alex',id:2},
     {name:'Bill'},
     {name:'Alex'}    
];

//es6 find
user = users.find(function(user){
    return user.name === 'Alex';
})
console.log(user);             //{name:'Alex',id:2}  好处:找到后不再执行

4、filter

/**
 * 场景一:假定有一个对象数组A,获取数组中指定类型的对象放到B数组中
 */

 var products = [
     {name:"cucumber",type:"vegetable"},
     {name:"banana",type:"fruit"},
     {name:"celery",type:"vegetable"},
     {name:"orange",type:"fruit"},
 ];

//es5
var filteredProducts = [];            //过滤后的数组
//-------------------------------遍历原数组---------------------------
for(var i=0;i<products.length;i++){
    if(products[i].type === 'fruit'){               //判断类型是水果
        filteredProducts.push(products[i]);          //将满足条件的对象push到数组中
    }
}
//console.log(filteredProducts);          //banana orange

//------------------------------------------------------------------

//es6 filter
//product接收products内的对象,返回类型是水果的内容
var filtered2 = products.filter(function(product){
    return product.type === 'fruit';           
})
//console.log(filtered2);                 //banana orange

5、reduce

/**
 * 场景一:计算数组中所有值的总和
 */

 var numbers = [1,3,4];

 var sum = 0;

//es5
 for(var i=0;i<numbers.length;i++){
     sum += numbers[i];
 }
 //console.log(sum);               //8

//------------------------------------------------------------------------------------------------

//es6 reduce
var sumValue = numbers.reduce(function(sum2,number){    //sum2和sum无关,sum2要初始化,此处为0
   // console.log(sum2);          //0 1 4
   return  sum2 + number;
},0);
//console.log(sumValue);             //8

6、every & some

/**
 * 场景一:计算对象数组中每个电脑的操作系统是否可用,大于16位操作系统表示可用,否则不可用
 */

 var computers = [
     {name:'Apple',ram:16},
     {name:'IBM',ram:4},
     {name:'Acer',ram:32}
 ];


//-------------------------------------------es5----------------------------------------------
 var everyComputersCanRunProgram = true;
 var someComputersCanRunProgram = false;

 for(var i=0;i<computers.length;i++){
     var computer = computers[i];
     if(computer.ram < 16){
         everyComputersCanRunProgram = false;
     }else{
         someComputersCanRunProgram = true;
     }
 }

 console.log(everyComputersCanRunProgram,someComputersCanRunProgram);       //false  true

//-------------------------------------------es6----------------------------------------------
//every:每个  一假即假                 some:任何,某个   一真即真
var every = computers.every(function(computer){
    return computer.ram > 16;             //返回每个ram都大于16,很明显只有一个满足,所以为false
})
console.log(every);             //false

var some = computers.some(function(computer){
    return computer.ram > 16;            //返回某个ram都大于16,虽然只有一个满足,但是为true
})
console.log(some);                 //true

三.基础语法

1、let & const

//var
function testVar(){
    var a = 30;
    if(true){
        var a = 50;
        console.log(a);         //50
    }
    console.log(a);             //50
}
testVar();

//----------------相对var而言,let有域的概念--------------------------------------

//let
function testLet(){
    let a = 30;
    if(true){
        let a = 50;
        console.log(a);           //50  let定义,a只在if的{}内有效
    }
    console.log(a);               //30
}

testLet();


//const:常量,一旦赋值,值不可修改
const x = 10;
x = 100;                  //报错

2、箭头函数

/**
 * 箭头函数解决问题:
 * 1.缩减代码
 * 2.改变this指向
 */

//--------------------------------未经缩减,未使用箭头函数的原始代码--------------------------------
const double = function(num){
    return num * 2;
}
console.log(double(3));                   //6

//--------------------------------去掉function的箭头函数-----------------------------------------
const double = (num) => {
    return num * 2;
}
console.log(double(10));                   //20

//--------------------------------去掉function和{}的箭头函数-------------------------------------
//只有一条语句可以去掉{}
const double = (num) => num * 2;
console.log(double(5));                       //10

//--------------------------------去掉()和{}的箭头函数------------------------------------------
const double = num => num * 2;
console.log(double(4));                         //8

//--------------------------------把后面内容括起来的箭头函数--------------------------------------
const double = (num => num * 2);
console.log(double(22));                //44

//--------------------------------两个参数无{}的箭头函数--------------------------------------
const double = (num1,num2) => num1 + num2;
console.log(double(5,4));                  //9

//--------------------------------两个参数有{}的箭头函数---------------------------------------------
const double = (num1,num2) => {
   sum = num1 + num2;
   return sum;
}
console.log(double(1,6));                      //7

3、 模板字符串``

//通过``可以分行写,方便省事,不易出错
let ele = `
<h3>${makeUppercase('Hello')},${name}!</h3>
<p>这是ES6的新方法</p> 
`;
document.getElementById('con').innerHTML = ele;

4、增强对象字面量

说实话,一开始看到这个名字,一脸懵逼,完全不知道在说啥,学完懂了!通俗说就是把key:value一致的省略一个留一个以及方法的缩减,看代码后秒懂:

/**
 * 增强对象字面量
 * 解决问题:缩减代码
 */

//-----------------------------------------原始代码------------------------------------------
function createBookShop(inventory){
    return {
        inventory:inventory,   
        inventoryValue:function(){
            return this.inventory.reduce((total,book) => total + book.price,0)     //初始值为0
        },
        priceForTitle:function(title){
            return this.inventory.find(book => book.title === title).price;
        }
    }
}

//--------------------------------------增强对象字面量代码------------------------------------------
function createBookShop(inventory){
    return {
        inventory,      //改动1:key:value一致,保留一个
        inventoryValue(){            //改动2:方法去掉 ':function'
            return this.inventory.reduce((total,book) => total + book.price,0)     //初始值为0
        }, 
        priceForTitle(title){       //改动3:方法去掉 ':function'
            return this.inventory.find(book => book.title === title).price;
        }
    }
}

const inventory = [
    {title:'Vue',price:100},
    {title:'React',price:50},
];

const bookShop = createBookShop(inventory);

console.log(bookShop.inventoryValue());               //150
console.log(bookShop.priceForTitle("Vue"));           //100

5、函数参数默认值

//优势:优化代码
//method="GET"就是参数默认值
function makeAjaxRequest(url,method = "GET"){
    return method;
}
console.log(makeAjaxRequest('google.com'));            //GET
console.log(makeAjaxRequest('google.com',"POST"));         //POST


//实例:
function User(id){
    this.id = id;
}
console.log(new User(1));                 //User{id:1}


function randomId(){
    return Math.random() * 9999999;
}

console.log(new User(randomId()));            //User{id:..}


function createAdminUser(user){
    user.admin = true;
    return user;
}

console.log(createAdminUser(new User(randomId())));            //User{id:..,admin:true}


//优化写法
function createAdminUser(user = new User(randomId())){
    user.admin = true;
    return user;
}

console.log(createAdminUser(user));          //User{id:..,admin:true}


//可以发现上面需要不断的传入id值,优化后直接传入user即可

6、展开运算符

实际就是...可以更快更便捷的操作数组.

//不需要传入固定参数个数
function addNumbers(...numbers){
    return numbers.reduce((sum,num) => {
        return sum + num;
    },0)
}

console.log(addNumbers(1,2,3,4,5,6,7,8)); 
//---------------------------------------------------------------------------------
var defaultColors = ["red","green"];
var favoriteColors = ["orange","yellow"];
//concat  连接两个数组
defaultColors = defaultColors.concat(favoriteColors);
console.log(defaultColors);                //['red','green','orange','yellow']

//-----------------------------------使用展开运算符----------------------------------------------
console.log([...defaultColors,...favoriteColors]);     //['red','green','orange','yellow']



var fallColors = ['fire red','fall orange'];
console.log([...fallColors,...defaultColors,...favoriteColors]);   //['fire red','fall orange

7、解构

//对象解构

var expense = {
    type:'es6',
    amount:"45"
};
//------------------------------------笨方法---------------------------------------
var type = expense.type;
var amount = expense.amount;
console.log(type,amount);             //es6  45

//---------------------------------------解构------------------------------------
//{此处内容要和对象的变量名一致}
const { type,amount } = expense;
console.log(type,amount);                 //es6  45
//数组解构
const names = ["tt","wf","ll"];

//解构
const [name1,name2,name3] = names;
console.log(name1,name2,name3);              //tt wf ll

//返回数组个数
const {length} = names;
console.log(length);                       //3

//结合展开运算符
const [name,...rest] = names;
console.log(name,rest);              //tt  ['wf','ll']

let a,b;
[a,b] = [100,200];
console.log(a,b);                //100,200

8、面向对象

//类Car
class Car{
    constructor({title}){
        this.title = title;
    }
    drive(){
        return 'vroom';
    }
}

//Toyota类集成Car类
class Toyota extends Car{
    constructor(options){
        super(options);
        this.color = options.color;
    }
}

const toyota = new Toyota({color:'red',title:'Focus'});
console.log(toyota);              //Toyota{title:'Focus',color:'red'}
console.log(toyota.drive());            //vroom

9、generator生成器

/**
 * generator生成器
 * 可以返回多次的函数
 */

 function* numbers(){
    yield;
 }

//会返回一个Iterator实例, 然后再执行Iterator实例的next()方法, 那么这个函数才开始真正运行, 并把yield后面的值包装成固定对象并返回,直到运行到函数结尾, 最后再返回undefined; 

 const gen = numbers();
//调用next()菜可以执行
 console.log(gen.next());                //false
 console.log(gen.next());                //true

//斐波那契数列
function fib(max){
    var a = 0,b = 1,arr = [0,1];
    while(arr.length < max){
        [a,b] = [b,a+b];
        arr.push(b);
    }
    return arr;
}
console.log(fib(5));                 //0,1,1,2,3

//----------------------------生成器--------------------------------------
function* fib(max){
    var a = 0,b = 1,n = 0;
    while(n < max){
        yield a;
        [a,b] = [b,a+b];
        n++;
    }
    return ;
}

for(var x of fib(10)){
    console.log(x);                     //0,1,1,2,3,5,8,13,21,34
}

//-------------------------------------------------------------------------------------------------

//Generator函数返回的Iterator运行的过程中,如果碰到了yield, 就会把yield后面的值返回, 此时函数相当于停止了, 下次再执行next()方法的时候, 函数又会从上次退出去的地方重新开始执行;如果把yield和return一起使用的话, 那么return的值也会作为最后的返回值, 如果return语句后面还有yield, 那么这些yield不生效:
function* gen() {
    yield 0;
    yield 1;
    return 2;
    yield 3;
};
let g = gen();
console.log(g.next(),g.next(),g.next(),g.next());
//{ value: 0, done: false } { value: 1, done: false } { value: 2, done: true } { value: undefined, done: true }

//------------------------------------------------------------------------------------------------
//Iterator的return的值不会被for...of循环到 , 也不会被扩展符遍历到, 以下Demo的return 2 和yield3完全不生效了.
function* gen() {
    yield 0;
    yield 1;
    return 2;
    yield 3;
};
let g = gen();
console.log([...g]); //输出:[ 0, 1 ]
for(let foo of g) {
    console.log( foo ); //输出 0, 1
}




//迭代器方法
// function profileIterator(profiles){
//     let nextIndex = 0;
//     return {
//         next:function(){
//             return nextIndex < profiles.length ?
//             {value:profiles[nextIndex++],done:false}:
//             {value:undefined,done:true}
//         }
//     }
// }


//生成器方法
function* profileIterator(){
    yield data[0];
    yield data[1];
    yield data[2];
}

10、map

/**
 * map
 * 键值对:与对象不同的是键和值可以是任何类型
 */

const map1 = new Map();

//设置key键
const key1 = 'something',
      key2 = {},
      key3 = function(){};


//为key设置value值
map1.set(key1,'Value of key1');
map1.set(key2,'Value of key2');
map1.set(key3,'Value of key3');

//根据key获取对应的value
console.log(map1.get(key1));                //Value of key1
console.log(map1.get(key2));                //Value of key2
console.log(map1.get(key3));                //Value of key3

//获取对应的value数量
console.log(map1.size);                   //3

//for...of遍历map1中的key value
for(let [key,value] of map1){
    console.log(`${key} = ${value}`);             
}

// something = Value of key1
// [object Object] = Value of key2
// function (){} = Value of key3


//only key
for(let key of map1.keys()){
    console.log(key);
}

//only value
for(let value of map1.values()){
    console.log(value);
}

//forEach遍历map1
map1.forEach((value,key) => {
    console.log(`${key} = ${value}`);
})

//将map1转化为正常的数组
const keyValueArray = Array.from(map1);
console.log(keyValueArray);


//将map1中key转为数组
const keyArr = Array.from(map1.keys());
console.log(keyArr);

//将map1中value转为数组
const valueArr = Array.from(map1.values());
console.log(valueArr);

11、set

/**
 * 集合:可以存储任何数据类型,并且是唯一的(不重复的值)
 */

 const set1 = new Set();

 //往set1中添加数据
 set1.add(100);
 set1.add("String");
 set1.add({name:"tt"});
 set1.add(true);
 set1.add(100);           //不可以重复添加,无作用

 console.log(set1);                //Set(4){100,'String',{...},true}


 const set2 = new Set([1,true,'string']);
 console.log(set2);                  //Set(3){1,true,'string'}

 //计算set1中的数据个数
 console.log(set1.size);            //4

 //检查set中是否拥有对应的值
 console.log(set1.has(100));          //true

 console.log(set1.has({name:'tt'}))              //false  匹配的是地址
 console.log({name:'tt'} === {name:'tt'})         //false


 //删除set中内容
 set1.delete(100);
 console.log(set1);

 //for...of遍历set
 for(let item of set1){
     console.log(item)
 }

 //forEach遍历
 set1.forEach(value => {
     console.log(value)
 })


 //将set转化为数组
const setArray = Array.from(set1);
console.log(setArray);

12、 promise

/**
 * 构造函数:promise
 * 一个非常牛逼闪电的东西!
 */

 let promise = new Promise((resolve,reject) => {
    // resolve();           //执行then
    reject()                 //执行catch
 });
//  console.log(promise);            

promise
    .then(() => console.log("成功!没有任何问题!"))
    .then(() => console.log("成功!可以无限调用then方法"))
    .catch(() => console.log("uh oh,出现了重大问题!"))

13、fetch Apis

 /**
 * new http:fetch
 * 一个基于promise的请求方法,更简单快捷
 */
let promise = new Promise((resolve,reject) => {
     setTimeout(() => {
         resolve();
     },3000)
})

promise
    .then(() => console.log("成功!没有任何问题!"))
    .then(() => console.log("成功!可以无限调用then方法"))
    .catch(() => console.log("uh oh,出现了重大问题!"))


//------------------------------------------fetch---------------------------------
let url = "http://jsonplaceholder.typicode.com/posts";

fetch(url)
    .then(response => response.json())                  //json解析
    .then(data => console.log(data))
    .catch(err => console.log("error:"+err))            //在posts前面错误才会打印


console.log(fetch);
//获取本地纯文本数据
function getText(){
    fetch("test.txt")
        .then((res) => res.text())                   //文本内容
        .then(data => {
            // console.log(data);
            document.getElementById("output").innerHTML = data;
        })
        .catch(err => console.log(err))
}

//获取本地json数据
function getJson(){
    fetch("posts.json")
        .then((res) => res.json())                   //json解析
        .then(data => {
            // console.log(data);
            let output = '';
            data.forEach((post) => {
                output += `<li>${post.title}</li>`;
            })
            document.getElementById("output").innerHTML = output;
        })
        .catch(err => console.log(err))
}

//请求网络接口
function getExternal(){
    fetch("https://api.github.com/users")
        .then((res) => res.json())
        .then(data => {
            // console.log(data);
            let output = '';
            data.forEach((user) => {
                output += `<li>${user.login}</li>`;
            })
            document.getElementById("output").innerHTML = output;
        })
        .catch(err => console.log(err))
}

14、封装fetch库(增删改查)

/**
 * 封装fetch
 * 更快更简单的请求数据
 * 版本:1.0.0
 */

 class EasyHttp{
     //get
     get(url){
         return new Promise((resolve,reject) => {
            fetch(url)
                .then(res => res.json())
                .then(data => resolve(data))
                .catch(err => reject(err))
         }) 
     }

     //post
     post(url,data){
        return new Promise((resolve,reject) => {
           fetch(url,{
               method:'POST',
               headers:{
                   'Content-type':'application/json'
               },
               body:JSON.stringify(data)
           })
               .then(res => res.json())
               .then(data => resolve(data))
               .catch(err => reject(err))
        }) 
    }

    //put
    put(url,data){
        return new Promise((resolve,reject) => {
           fetch(url,{
               method:'PUT',
               headers:{
                   'Content-type':'application/json'
               },
               body:JSON.stringify(data)
           })
               .then(res => res.json())
               .then(data => resolve(data))
               .catch(err => reject(err))
        }) 
    }

    //delete
    delete(url){
        return new Promise((resolve,reject) => {
           fetch(url,{
               method:'DELETE',
               headers:{
                'Content-type':'application/json'
               }
           })
               .then(res => res.json())
               .then(data => resolve("数据删除成功!"))
               .catch(err => reject(err))
        }) 
    }
 }


const http = new EasyHttp;

//请求数据
// http.get("http://jsonplaceholder.typicode.com/users")
//     .then((data) => {
//         console.log(data);
//     })
//     .catch((err) => {
//         console.log(err);
//     })


//传输数据
const data = {
    name:'tt',
    username:'yy',
    email:'123@qq.com'
};

//post user
// http.post("http://jsonplaceholder.typicode.com/users",data)
//     .then(data => console.log(data))
//     .catch(err => console.log(err))


//update user
// http.put("http://jsonplaceholder.typicode.com/users/2",data)
//     .then(data => console.log(data))
//     .catch(err => console.log(err))


//delete user
http.delete("http://jsonplaceholder.typicode.com/users/2")
    .then(data => console.log(data))
    .catch(err => console.log(err))

15、async和await(es7)

async:返回promise对象

await:请求成功后执行

//请求数据
async function getUsers(){
    const response = await fetch("http://jsonplaceholder.typicode.com/users");
    const data = await response.json();
    return data;
}

getUsers()
    .then(users => console.log(users));

16、async封装fetch(2.0版本)

/**
 * 封装fetch
 * 更快更简单的请求数据
 * 版本:2.0.0
 */

class EasyHttp{
    //get
    async get(url){
        const response = await fetch(url);
        const resData = await response.json();
        return resData;
    }

    //post
    async post(url,data){
       
        const response = await fetch(url,{
              method:'POST',
              headers:{
                  'Content-type':'application/json'
              },
              body:JSON.stringify(data)
        });
        const resData = await response.json();
        return resData;
   }

   //put
   async put(url,data){
       
        const response = await fetch(url,{
              method:'PUT',
              headers:{
                  'Content-type':'application/json'
              },
              body:JSON.stringify(data)
        });
        const resData = await response.json();
        return resData;
   }

   //delete
   async delete(url){
       
        const response = await fetch(url,{
              method:'DELETE',
              headers:{
               'Content-type':'application/json'
              }
        });
        const resData = await "数据删除成功!";
        return resData;
   }
}

const http = new EasyHttp;

//请求数据
// http.get("http://jsonplaceholder.typicode.com/users")
//     .then((data) => {
//         console.log(data);
//     })
//     .catch((err) => {
//         console.log(err);
//     })



//传输数据
const data = {
    name:'tt',
    username:'yy',
    email:'123@qq.com'
};
//post user
// http.post("http://jsonplaceholder.typicode.com/users",data)
//     .then(data => console.log(data))
//     .catch(err => console.log(err))


//update user
// http.put("http://jsonplaceholder.typicode.com/users/2",data)
//     .then(data => console.log(data))
//     .catch(err => console.log(err))


//delete user
http.delete("http://jsonplaceholder.typicode.com/users/2")
    .then(data => console.log(data))
    .catch(err => console.log(err))

 

© 著作权归作者所有

wftt
粉丝 11
博文 38
码字总数 24507
作品 0
海淀
前端工程师
私信 提问
ES6-7

JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMAScript 6 Promises规范为中心,着重向各位读者介绍JavaScr...

掘金官方
2018/01/05
0
0
es6对象扩展

es6对于对象做了很多扩展,现做以下总结。 特性: ES6 允许直接写入变量和函数,作为对象的属性和方法。 Object.is()方法比较两个值是否严格相等,与===的不同之处在于,+0不等于-0;NaN等于...

tiancai啊呆
2017/10/06
0
0
ES6学习笔记(const和let)

前言:这周工作的中心开始倾向于前端了,自己虽然是个后端工程师,不过最终的期望还是倾向于全栈的,自己今年也有意朝着这个方向去努力,因为公司属于创业公司,如果每个人设计的技术层面会更...

程序员小哥哥
2018/06/23
0
0
【译】如何从头开始搭建React,Webpack4,Babel7工程

这是一篇非常适合新手的教程。 目录: 你将会学习到的知识 建立项目 配置webpack 配置Babel 编写React组件 HTML webpack plugin webpack dev server 总结 你将会学习到的知识 如何安装及配置...

EniviaQ
02/12
0
0
JavaScript杂谈

浏览器内的事件队列 众所周知JavaScript是基于单线程运行的,同时又是可以异步执行的,一般来说这种既是单线程又是异步的语言都是基于事件来驱动的,恰好浏览器就给JavaScript提供了这么一个...

掘金官方
2017/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
9
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部