ECMAScript 的一个颠覆性版本更新 - 面向对象编程(类、对象-- 封装、继承、多态)
let 声明变量;
特点:
//1、变量无法提升;
console.log(b);//b is not defined
let b='小明';
//2、变量无法重复定义;
let b = '小红';
let b = '小霞';
console.log(b);//Identifier 'b' has already been declared
//3、有块级作用域;;
{
let b='郭德纲';
}
console.log(b);//b is not defined
常量主要用来保存一些初始信息,不允许修改;
// 1. 常量无法重新赋值
const age1 = 100;
age1 = 101; // 常量 一旦赋值,不能改变!
console.log(age1);
// 2. 常量只能也必须在 创建时赋值
const age2; //报错: Missing initializer in const declaration
console.log(age2);
// 3. 无法变量提升
console.log(age3); // 报错: age is not defined
const age3 = 1;
// 4.有 块级作用域
if(true){
const num4 = 100;
}
console.log(num4); // 报错: num is not defined
// 5.无法重复声明
const num5 = 1;
const num5 = 2; // Identifier 'num' has already been declared
概念:一种方便获取对象和数组中值的方式;
概念:使用对象解构自动将对象 同名属性 赋值给 同名变量;
let a={
name: '小明',
age: 19,
eat: function () {
console.log('我叫'+a.name+'今年'+a.age+'岁了')
return '下午好';
}
}
//把对象中的属性值赋值给了 同名 变量;
let {name,age,eat}=a;
let c=name;
console.log(name,age,eat());//小明 19 下午好;
console.log(c);//小明;
//情况1;变量多于对象属性;则多余的那个变量会打印undefined;
let {name,age,eat,key}=a;// key -> undefined
//情况2;若变量少于对象属性,则正常打印属性值;
let {name}=a;//小明;
相当于创建n个变量,并且从数组中 【按顺序】 取出元素设置给变量;
//声明一个变量;
let a=[1,2,3,4,5,6,7,8];
//将数组解构取出;
let [p,b,c,d,e,f,g,h]=a
console.log(f);// 6;
console.log(b);// 2;
console.log(c);// 3;
问题:有些函数有多个形参,但实际使用时,需要指定传入任意位置的参数,传统语法无法实现;
//一个函数有三个形参,但是有一个需要是默认值,其他两个是用户传入的值;
function fn({a=1,b=2,c=3}) {
console.log(a,b,c);//1 9 8
}
let obj={b:9,c:8};
fn(obj);
? 箭头函数(Arrow Function),并且简化了函数定义。
注:1、只针对于 匿名函数,命名函数不能使用;
? 2、箭头函数的this在创建时就确定了,是上下文中的this;
// const a=function (b) {
// console.log(89+b);
// console.log(78);
// }
//简化后;
const a=b=>{
console.log(89+b);
console.log(78);
}
a(39) //128 78
:function 变为 =>;
参数:
参数只有1个 省略小括号;
参数0个或多个,无法省略小括号;
函数体一行 有返回值 省略{} 的 同时 【必须省略 return】
const a=function () {
return 99;
}
//简化后;
const a=()=>99;
console.log(a());//99
this指向改变;
var a = {
nam: '小明',
eat: function () {
console.log(this);
//使用箭头函数会发生this指向改变;
setTimeout( () =>{
console.log(this);//此时的this不在是window;
},1000)
},
}
console.log(a.eat())
let name = '妲己'
let gender = '女'
let skill = '傻笑'
//方式一:手动将同名的变量的值设置给对象中的同名属性;
let hero = {
name: name,
gender: gender,
skill: skill
};
//方式二:对象属性赋值简写;
/注意:属性名和值相同可以简写,否则不要这么做
let hero2 = {
name,
gender,
skill
};
const person = {
//sayHi: function() {
// console.log('Hi~~~')
//}
// 可以省略 :function ;
sayHi() {
console.log('Hi~~~')
}
}
person.sayHi();
概念:将对象中的成员自动添加到 另一个对象中;
//定义对象;
const a={
name: '小明',
age: 18,
eat: function () {
console.log("我叫"+a.name+"今年"+a.age)
return 576;
}
}
const b={
name: '小红',
//对象展开;会把小红覆盖掉;
...a,
}
console.log(b);
概念:将数组中的元素自动添加到另一个数组中;
//定义数组;
const a=[1,2,3,4,5,6,7];
const c=['a','b','c']
const b=['a','b',1,2,3,4,5,...a,...c];
console.log(b);
本质:就是一个字符串;
特点:
- 可以换行;
- 挖坑(占位符) ,用来填充变量值;
const b='hahahha';
const a=`
望庐山瀑布
日照香炉生${b};
遥看瀑布挂前川;
飞流直下三千尺;
疑似银行落九天
`;
console.log(a);
node
模块;注:node有很多模块,它在我们安装时就内置在了里面;直接可以使用但是需要我们自己导入;
? 1、浏览器不能读取计算机的文件;
? 2、但是node.js可以读取计算机的文件;
//文件的读;
//导包:可以理解为调用了node的内置的方法;
const fs = require('fs');
//查文档找读取文件的使用方式;
fs.readFile('./nav.text','UTF-8' ,((err, data) => {
console.log(err);
console.log(data);
}))
//写文件;
const a='晚上好晚上好';
const fs=require('fs');
fs.writeFile('./nav.text',a,err=> {
console.log(err)//Null 表示文件写入成功;
})
导入模块使用:require()
导出模块使用:module.exports
;
module.exports
赋值后面的会把前面的覆盖;/自己写的模块;
//写自己的变量;
const name = '中午好';
const age = 18;
//暴露出去;module 是关键字,全局变量
module.exports = {
name,
age,
sayhi() {
console.log('你好啊')
}
}
//导包;注意:要写路径;
const qw = require('./text/zi');
//调用;
console.log(
qw.age,
qw.name,
qw.sayhi()
);
绝大多数的代码都是同步的
NodeJS中有大量的异步方法,判断依据:如果有回调函数 大部分情况都是异步
判断依据二:跟 网络 、硬盘、内存 打交道的操作 一般 都是 异步的!
定时器
fs读写文件
ajax (浏览器)
jQuery动画回调函数(浏览器)
$(‘div‘).animte({height:100},function(){})
注:node.js文件中的相对路径,是相对与终端中的路径;
注:直接可以使用;
? 1.nodeJS 不要使用相对路径,而要使用绝对路径;
//引入模块;
const fs=require('fs');
//拼接路径;注:拼接的路径最前面不要加 . ;
const fsfile=__dirname+'/text/test.text';
//读取文件;
fs.readFile(fsfile,'utf-8',function (err,data) {
if (err==null) {
console.log('我读取成功了');
} else{
console.log('我读取失败了')
console.log(err);
}
})
模块提供用于处理文件路径和目录路径的实用工具;
//使用方法;导入模块;
const path = require('path');
join
方法;
//导包;
const fs=require('fs');
const path=require('path');
//生成绝对路径;
c=path.join(__dirname,'text','test.text');//可以不加`/`不加`.`,可以智能改错;
c=path.join(__dirname,'./text/test.text');
//读取文件;
fs.readFile(c,'utf-8',(err,data) => {
if (err==null) {
//返回读取到的文件内容;
console.log(data)
}
})
node内置的服务器模块,可以让程序员方便的开发web服务器程序;
http模块。开启的服务是http服务,访问时要带上;
http://
创建服务器;
//导入内置模块;
const http=require('http');
//创建服务器;
const server=http.createServer(function (request,response) {
//返回响应;
response.end('wo fan hui le');
});
//开启服务器开始监听;参数:匿名函数是开启后的回调函数;
// 参数1 端口号
// 参数2 监听的地址 省略的话就是本机,
// 参数3 开启之后的回调函数
server.listen(8889,function (err) {
if (err==null) {
console.log('开启成功了');
} else {
console.log('开启失败')
}
})
响应中英文:
//响应英文;
//导入内置模块;
const http=require('http');
//创建服务器;
const server=http.createServer(function (request,response) {
//设置请求头,可以访问 中文 文件;
response.setHeader('content-type','text/plain;charset=utf-8');
//返回响应;
// response.end('wo fan hui le');//若是英文则可以直接访问;
response.end('我返回了');//若是中文则需设置请求头;
});
//开启服务器开始监听;参数:匿名函数是开启后的回调函数;
server.listen(8889,function (err) {
if (err==null) {
console.log('开启成功了');
} else {
console.log('开启失败')
}
})
响应网页;
//导入内置模块;
const http=require('http');//用于创建服务器;
const fs = require('fs');//用于读写文件;
const path=require('path');//用于生成路径;
//创建服务器;
const server=http.createServer(function (request,response) {
//接收请求地址并转码;不然会乱码;
const requestUrl = decodeURI(request.url);
//拼接路径;
const p_flie=path.join(__dirname,'./web',requestUrl);
//拼接后的路径被写死了,导致可以请求成功但是响应结果依然是hrml结构;
// const p_flie=path.join(__dirname,'./web/index.html');
//由于请求头的设置,导致虽然读取到了html文件,但是无法解析;plain:表示普通文本;
// response.setHeader('content-type','text/plain;charset=utf-8');
/*
* 读取文件;此时的参数中不需要再设置编码格式,因为在html中,已有utf-8了;
* 如果设置了会由于编码格式的限制导致无法解析图片;*/
fs.readFile(p_flie,function (err, data) {
if (err==null) {
console.log('我读取到文件了');
//读取成功则返回响应;
response.end(data);
} else{
console.log('我没读到文件');
//此处设置请求头,时因为下面的`h1`标签;
response.setHeader('content-type','text/html;charset=utf-8');
// 找不到就 提示404
response.end(`<h1> 404 你要的页面去火星了</h1>`);
}
})
});
//开启服务器开始监听;参数:匿名函数是开启后的回调函数;
server.listen(8889,function (err) {
if (err==null) {
console.log('开启成功了');
} else {
console.log('开启失败')
}
})
获取请求的方式;
GET
或POST
;express
模块;get
路由;//导包;
const express=require('express');
//创建服务器对象;
const app=express();
/*
* 托管静态资源,实现服务器的功能;
* 参数为中间件的处理函数;此处的
* 地址可以用相对路径./或../;*/
app.use(express.static('web'));
//开启服务器;
app.listen(3000,err=>{
if (!err) {
console.log('开启成功');
}
})
get
请求时;客户端提交的数据,在url后面;可以直接获取;//导包;导出模块;
const express = require('express');
const fs = require('fs');
const path = require('path');
/*
* 创建服务器对象;创建一个Express应用程序。
* 该express()函数是express模块导出的顶级函数。*/
const app = express();
//注册路由;注意:不要加 .
app.get('/jokes', function (request, response) {
//创建路径;
const fsfile = path.join(__dirname, './jokes.json');
//读取文件;
fs.readFile(fsfile, function (err, data) {
//判断;
if (!err) {
console.log('我读取到文件了');
//把读取到的文件进行转换;
const arr = JSON.parse(data);
//获取地址的输入信息;
const num = request.query.num;
//定义空数组;
const jokes = [];
//循环获取一定数量的笑话,并存放到数组中;
for (let i = 0; i < num; i++) {
//获取随机数;
const ram = parseInt(Math.random() * arr.length);
jokes.push(arr[ram])
}
//判断笑话数是否在此范围;
if (num<arr.length) {
//返回响应;定义一个对象用于返回;
response.send({
num,
msg: '获取成功',
jokes,
});
} else {
response.send({
num,
msg: '获取失败,请重新输入',
});
}
} else {
console.log('我没有读取到文件')
}
})
});
//开启服务器开始监听;
app.listen(8889, function (err) {
//判断;
if (!err) {
console.log('开启服务器成功')
} else {
console.log('开启服务器失败了');
}
})
post
路由;/单文件上传;
//导包;
const express = require('express');
//用于生成路径;
const path = require('path');
//中间件;用于处理上传的文件;
const FileUpload = require('express-fileupload');
//创建服务器对象;
const app = express();
//处理中间件;
app.use(FileUpload());
//注册路由;
app.post('/fileupload', function (resquest, response) {
//获取文件的名字;resquest.files==>获取的是个对象;
//多文件上传时;icon==>是个数组;
const filename = resquest.files.icon;
//生成文件路径;
const filepath = path.join(__dirname, './files', filename.name);
//移动到文件夹中;每一个文件对象都有 mv 方法;
filename.mv(filepath, function (err) {
//判断;
if (!err) {
console.log('文件移入成功了')
} else {
console.log('文件移入失败了哦')
}
})
})
//开启路由开始监听;
app.listen(8889, function (err) {
//判断;
if (!err) {
console.log('开启成功了')
} else {
console.log('开启失败了')
}
})
/验证用户名;
//导包;
const express=require('express');
//导包,中间件;
const bodyParser=require('body-parser');
//创建服务器;
const app=express();
//解析中间件;
app.use(bodyParser.urlencoded({extended: false}))
//注册路由;默认的post请求无法获取到提交的数据;
app.post('/username',function (request,response) {
//定义一个用户名的数组来模拟;
const arruser=['孙悟空','猪八戒','唐僧','沙和尚','如来']
//获取用户提交的数据;
const username=request.body.username;
console.log(request.body)
//判断数组中是否有此用户名;
const num=arruser.indexOf(username)
if (num==-1) {
//返回响应;
response.send({
msg: '恭喜你,可以注册',
code: 200,
});
}else{
response.send({
msg: '很遗憾,已被注册',
code: 400,
})
}
})
//开启服务器开始监听;
app.listen(8889,function (err) {
//判断;
if (!err) {
console.log('开启成功了')
} else{
console.log('开启失败了哦')
}
})
node 的一个
全局模块
安装了之后可以自动检测文件修改,自动重新运行
- 任意位置执行
npm i nodemon -g
- 安装完毕之后
node xxx
- 换成;
nodemon xxx
概念:浏览器使用
ajax
时,如果请求了的接口地址 和当前打开的页面
地址不同源
称之为跨域;
协议
地址与
端口均一致;目前最主流也是最简单的解决方案;
工作原理:
服务器在返回响应报文的时候,在响应头中设置一个允许的header ;
res.setHeader(‘Access-Control-Allow-Origin‘, ‘*‘);
让浏览器准许访问来自不同服务器上的指定资源;
// 注册路由;
app.post('/corsPOST', (request, response) => {
console.log('请求过来了-post');
// 设置允许跨域
response.header('Access-Control-Allow-Origin', '*');
response.send('/post');
});
注:
- get请求时:如果第一次请求成功,则由于缓存的存在,那么如果去掉允许跨域的代码片段;依然可以请求成功;
- 虽热有跨域问题的出现,但是依然可以发送请求,但是无法接收响应的结果;
基层原理;
app.use((req, res, next) => {
//任何请求都会进入这个use中间件
res.setHeader('Access-Control-Allow-Origin', '*')//设置响应头
next()//执行下一个中间件
})
express
的中间件cors
,它的作用是自动给每一个res设置默认请求头;需要下包 npm i cors
//ajax请求;
$(".get").click(function () {
$.ajax({
url: "http://192.168.156.26:8889/list",
success(backData) {
console.log(backData);
}
})
})
//导包;
const express=require('express');
//中间件;
const cors=require('cors');
//创建服务器对象;
const app=express();
//使用中间件来设置默认请求头;
app.use(cors());
//注册路由;
app.get('/list',function (request,response) {
console.log('我被请求了==get');
response.send('我返回了');
});
app.post('/add',function (request,response) {
console.log('我被请求了==post');
response.send('我返回了')
})
//开启服务器,开始监听;
app.listen(8889,function (err) {
if (!err) {
console.log('开启成功');
}
})
核心原理:如果script标签的src属性的请求,服务器返回的是一个函数调用。则浏览器会执行这个函数;
本质:会动态的在页面的顶部创建一个script标签,并进行解析为js一个函数的调用,并传入有个形参,之后会自动移出;
//用JSONP来解决跨域;必须是GET请求;
<input type="button" value="jsonp跨域方案" class="jsonp">
$('.jsonp').click(function () {
$.ajax({
url: 'http://192.168.156.26:3000/jsonpApi',
data:{
name:'rose',
friend:'jack',
skill:'抗冻'
},
dataType:'jsonp',//响应内容为jsonp格式的;
success(backData) {
console.log(backData);
}
})
})
// 导包
const express = require('express')
// 创建服务器
const app = express()
// 注册路由
app.get('/jsonpApi',(request,response)=>{
// 响应内容 jsonp的接口 返回数据用`jsonp`
response.jsonp({
msg:"请求成功",
code:200,
info:"欢迎再来"
})
})
// 开启服务器
app.listen(3000,(err)=>{
if(!err){
console.log('success');
}
})
原理:
君子之约
,只要是jsonp前端程序员都统一将参数名定义为callback函数调用格式
,通过传参的方式将响应数据返回给浏览器<script>
function doSomething(backData){
console.log("调用了");
console.log(backData);
}
</script>
//去请求3000端口,jsonpApi接口时,函数会被调用;
<script src="http://192.168.156.26:3000/jsonpApi?callback=doSomething">
</script>
原文:https://www.cnblogs.com/ywnh/p/12380624.html