console.log("hello world");在ES6出现之前使用var来定义变量,但var定义变量作用域是全局的,对于编程语言来说这是比较不规范的。
if(1){
var i=0;
}
console.log(i);对于C++这样的静态语言,则会报错i没有定义,在javascript中则是输出了0,而我们使用let定义变量。
if(1){
let uselet=0;
}
//console.log(uselet);
//Uncaught ReferenceError: uselet is not defined
//则会产生异常可见我们能使用let 就不要使用 var
const num=1000;
//num=999;
//Uncaught TypeError: Assignment to constant variable.
console.log("num:",num);值类型与引用类型
值类型:String Number Boolean undefined null
引用类型:Object Array Function
if(1){
//String
let name="gaowanlu";
//Number
let m=30;
//Boolean
let k=true;
//undefined
let u=undefined;
//null
let n=null;
}编程语言有两种:动态语言 静态语言
JavaScript属于前者,也就是说我们定义了变量,什么时候想改变它的数据类型就可以改变。
在C++中、一旦编码 int variable=1; 我们就无法把variable当float使用 在Javascript中 let i="javascript"; i=10; 这是完全可行的操作
if(1){
let v=1;
console.log(typeof(v));
v="string"
console.log(typeof(v));
}if(1){
let person={
name:"gaowanlu",
age:11
};
console.log(person.name);
console.log(person["name"]);
person.phone="133466377";
console.log(person);
console.log(person.phone);
let key="phone";
console.log(person[key]);
}if(1){
let array=['red',1,'guy'];
console.log(array[0]);
array[0]="yellow";
console.log(array);
//得到数组长度
console.log(array.length);
}if(1){
function hello(name){
if(typeof(name)=="string"){
console.log(name+" hello.");
return true;
}else{
return false;
}
}
hello("gaowanlu");
}/*
+ - * / 加减乘除
= 赋值
+= -= *= /= 加减乘除
% 取余
** 指数
++ -- 自加1 自减1
> >= < <= != == === 比较运算符
&& || ! 与 或 非
*/if(1){
let output=2>1?"2>1":"2<1";
console.log(output);
}/*
Falsy(false)
undefined
null
0
false
''
NaN
*/if(1){
console.log(1|2);//位或
console.log(1&2);//位或
}(省略)
/*
因为与大多数编程风格一样(Python除外):省略
if(){
if(){
}
}else if(){
if(){
}else{
}
}else{
}
*//*
与C/C++相同
switch(){
case __:_________;break;
case __:_________;break;
default:—————————break;
}
*/for 、 while、 do while、 for in、 for of
if(1){
for(let i=0;i<5;i++){
console.log(i);
}
let i=0;
while(i<5){
i++;
}
i=0;
do{
i++;
}while(i<5);
}if(1){
let person={
name:"gaowanlu",
age:19
};
for(let key in person){
console.log(key," : ",person[key]);
}
let colors=['red','green','blue'];
for(let index in colors){
console.log(colors[index]);
}
for(let val of colors){
console.log(val);
}
}省略
if(1){
let person={
name:"gaowanlu",
phone:"133466377",
call:function(){
console.log(this.name,this.phone);
this.class_sum+=1;
},
class_sum:0,
};
console.log(person);
person.call();
console.log(person);
}function create_obj(){
let person={
name:"gaowanlu",
phone:"133466377",
call(){//call()是class:function()的缩写
console.log(this.name,this.phone);
this.class_sum+=1;
},
class_sum:0,
};
return person;
}
if(1){
let obj=create_obj();
console.log(obj);
}function Circle(radius){
this.radius=radius;
this.show=function(){
console.log(this.radius);
}
}
if(1){
let cir=new Circle(10);
//如果没写new那么Circle内的this指向window,致命行为
cir.show();
}if(1){
let person={
name:"gaowanlu"
};
person.phone="133";//添加属性
delete person.name;//删除属性或者方法
console.log(person);
}if(1){
let person={
name:"gaowanlu",
age:19
};
for(let key in person){
console.log(person[key]);
}
for(let key of Object.keys(person)){
console.log(person[key]);
}
for(let entry of Object.entries(person)){
console.log(entry);
}
/*
Object.entries(person)=
[["name", "gaowanlu"],["age", 19]]
*/
}if(1){
let person={
name:"gaowanlu",
age:19
};
let another={};
for(let key in person){
another[key]=person[key];
}
console.log(another);
//使用Object.assign()
another= Object.assign({color:"yellow"},person);
console.log(another);//{color: "yellow", name: "gaowanlu", age: 19}
//使用{...objname}
another={...person};
}内存自动管理
if(1){
const message="gaowanlu";常用方法 //concat()
let name="gaowanlu";
console.log(name.concat(" hello ","YES"));模板语法 let show=`${name}fdfd${name}`;.split()将字符串切为数组 let numbers="1 2 3 4 5 6";
numbers=numbers.split(' ');
console.log(numbers);//[1,2,3,4,5,6]
}省略
Adding Elements 添加元素
if(1){
const numbers=[3,4,5];
//const数组我们不能修改,numbers但能修改数组的内部.push()在后面添加新元素
numbers.push(6,7,8);
console.log(numbers);//[3,4,5,6,7,8].unshift()在前面添加新元素
numbers.unshift(1,2);
console.log(numbers);//[1, 2, 3, 4, 5, 6, 7, 8].splice()在中间插入新元素
numbers.splice(2,0,'a','b');//从下标2开始,删除0个,插入a b
console.log(numbers);//[1, 2, "a", "b", 3, 4, 5, 6, 7, 8]
// .splice()第一个参数是插入位置下标,第二个参数删除几个元素,后面为新元素
}Finding Elements(Primitives)查找元素(值类型)
if(1){
const numbers=[1,2,3,4,5,1,2,3,4,5];.indexOf(el,start)查找第一个符合要求的元素
console.log(numbers.indexOf(5));//start为从那个下标开始查找
/* 4 即第一个符合要求的元素的下标,找不到返回-1 */.lastIndexOf()查找最后一个符合要求的元素
console.log(numbers.lastIndexOf(5));
/* 输出: 9 */.includes() 检查数组中有没有某个元素返回布尔值
console.log(numbers.includes(1));
}Finding Elements(Object)查找元素(对象)
if(1){
const course=[
{id:1,name:'a'},
{id:2,name:'b'}
];.find() 方法 返回第一个匹配的对象
var found=course.find(function(el){
return el.id==1&&el.name=='a';
});
console.log(found);
//{id: 1, name: "a"}.findIndex() 方法 返回第一个匹配的对象的下标
found=course.findIndex(function(el){
return el.id==1;
});
console.log(found);//输出:0
}箭头函数if(1){
const courses=[
{id:1,name:'a'},
{id:2,name:'b'}
];
const course=courses.find((el)=>{
return el.name==='a';
});
/*
(参数列表)=>{函数体},当只有一个参数是可以写为
参数列表=>{函数体}
*/
console.log(course);
}Removing Elements(删除元素)if(1){
const array=[1,2,3,4,5,6,7,8,9];.splice(index,count)
array.splice(2,3);//从下标2开始删除后面3个元素
console.log(array);//[1,2,6,7,8,9]Emptying an Array(清空数组)if(1){
let numbers=[1,2,3,4];
console.log(numbers);=[] 赋值清空
numbers=[];.length=0 清空
numbers=[1,2,3];
numbers.length=0;
console.log(numbers);.splice(0,numbers.length) 清空
numbers=[1,2,3];
numbers.splice(0,numbers.length);.pop()清空
numbers=[1,2,3,4];
while(numbers.length>0){
numbers.pop();
}
}Combining Arrays(组合和切割数组)if(1){.concat() 数组合并
let array_1=[1,2,3];
let array_2=[4,5,6];
let array_concat=array_1.concat(array_2);
console.log(array_concat);
//[ 1, 2, 3, 4, 5, 6 ].slice(start_index,end_index_after)切割数组
array_1=[1,2,3,4,5,6,7,8,9];
array_1=array_1.slice(2,4);
console.log(array_1);[...__,...__] 拼接数组
array_1=[1,2,3];
array_2=[4,5,6];
console.log([...array_1,"a",...array_2]);
//[ 1, 2, 3, 'a', 4, 5, 6]
}遍历数组if(1){
let array=[1,2,3,4,5,6,7,8,9];传统for循环
for(let i=0;i<array.length;i++){
array[i]=2*array[i];
}.forEach(function)
array.forEach(function(el){
console.log(el);
});
}Joining Arrays(连接数组元素)if(1){
let numbers=[1,2,3];
let string=numbers.join(",");
console.log(string);//1,2,3
}Sorting Arrays(数组排序)if(1){
let numbers=[1,2,5,3,2,7,8];.sort() 方法
numbers.sort();
/*
[
1, 2, 2, 3,
5, 7, 8
]*/
console.log(numbers);.reverse()方法 反转数组元素序列
numbers.reverse();
console.log(numbers);
/*[8, 7, 5, 3, 2, 2, 1]*/数组根据对象属性排序
let courses=[
{id:1,name:'gaowanlu'},
{id:2,name:'ming'}
];
courses.sort(function(obj_a,obj_b){
if(obj_a.id<obj_b.id) return 1;
if(obj_a.id>obj_b.id) return -1;
return 0;
});
console.log(courses);
//[ { id: 2, name: 'ming' }, { id: 1, name: 'gaowanlu' } ]
}检测数组中的元素if(1){
let numbers=[1,2,3];.every()
let result=numbers.every(function(el){//全部都是数组返回true
return typeof(el)=="number";
});
console.log(result);//true
numbers=[1,"ds"];.some()
result=numbers.some(function(el){
return typeof(el)=="string";
});
console.log(result);//true
}过滤数组元素if(1){.filter(function)
let numbers=[1,-1,2,3];
numbers=numbers.filter(function(el){
return el>=0;
});
console.log(numbers);//[ 1, 2, 3 ]
}数组映射if(1){
let numbers=[1,-1,2,3];.map()
let items=numbers.map(function(el){
return `'<li>'+el.toString()+'</li>';`
});
console.log(items);
//`[ '<li>1</li>', '<li>-1</li>', '<li>2</li>', '<li>3</li>' ]`
items=items.join("\n");
console.log(items);
/*`
<li>1</li>
<li>-1</li>
<li>2</li>
<li>3</li>
`*/
}缩减数组if(1){.reduce() 方法
let numbers=[1,2,3,4,5,6];
let sum=numbers.reduce(function(sum,cur){
return sum+cur;
});
console.log(sum);
//21
}if(1){
function SuperCar(){
console.log("Tesla");
}
let tesla=function(){
console.log("Tesla");
}
}if(1){ 使用arguments
let sum=function(a,b){
let sum=0;
for(let i of arguments){
sum+=i;
}
return sum;
}
console.log(sum(1,2,3,4,5));
//输出:15余下操作符
sum=function(none,...args){
return args.reduce(function(sum,cur){
return sum+cur;
});
}
console.log(sum(99,11,1,1));
//输出: 13参数默认值
sum=function(a=1,b=1){
return a+b;
}
console.log(sum());//输出: 2}
if(1){
let obj={
count:0,
data:"",
get num(){
return num;
},
set num(el){
this.data=el;
this.count+=1;
}
}
obj.num=1;
obj.num=2;
console.log(obj.count);//输出 2
}if(1){
try{
throw new Error("new Error");
}catch(err){
}finally{
}
}this指向对象本身
//面向对象编程有4个概念
//封装、抽象、继承和多态
//Encapsulation Abstraction Inheritance Polymorphism
/*
使用封装重新组合相关的变量和函数
这样我们可以减少复杂性、我们可以在程序的不同部分重用这些对象
或者在不同的程序中
通过抽象,我们隐藏细节和复杂性
只显示必要的部分
这种技术降低了复杂性、也隔离了代码的更改的影响
继承让我们可以消除多余的代码
用多态性我们可以避免写出复杂丑陋的选择性代码
*/
//Object
/*
JavaScript一切皆是对象
*/
//对象创建语法
//是一种简单的定义对象的方法
if(1){
let circle={
center:{
x:1,
y:3
},
radius:10,
};
console.log(circle);
//{ center: { x: 1, y: 3 }, radius: 10 }
//添加新属性或者方法
circle.show=function(){
console.log(this.center);
}
circle.show();
//{ x: 1, y: 3 }
}
//工厂函数
if(1){
let factory=function(){
let obj={};
obj.show=function(){
console.log("hello world");
}
return obj;
}
let new_obj=factory();
new_obj.show();
//hello world
}
//构造函数
if(1){
let constructor=function(){
this.show=function(){
console.log("hello world");
}
}
let new_obj=new constructor();
new_obj.show();
//hello world
}
//构造函数属性(Constructor Property)
/*
每个javascript中的对象都有一个叫构造函数的属性
它是一个用于创建这个对象的构造方法的引用
*/
if(1){
let circle=function(){
return {
show:function(){
console.log("hello world");
}
}
};
let new_obj=circle();
console.log(new_obj.constructor);
}
//添加删除属性(Adding/Removing Properties)
if(1){
let circle=function(){
return{
show:function(){
console.log("hello world");
}
}
};
let new_obj=circle();
console.log(new_obj);
//{ show: [Function: show] }
new_obj.data="gaowanlu";
console.log(new_obj);
//{ show: [Function: show], data: 'gaowanlu' }
new_obj["id"]=1234;
console.log(new_obj);
//{ show: [Function: show], data: 'gaowanlu', id: 1234 }
delete new_obj["show"];
console.log(new_obj);
//{ data: 'gaowanlu', id: 1234 }
}
//遍历或枚举对象
if(1){
let obj={
id:"gaowanlu",phone:"1234"
};
for(let i in obj){
console.log(obj[i]);
}
//1234
}
//Hide the details Show the essentials
/*
抽象意味着我们应该隐藏细节和复杂的部分,只显示或暴露必要的部分
*/
//私有属性与方法
if(1){
let Circle=function(){
//@private
let data=0;
//@public
this.show=function(){
data+=1;
console.log(data);
}
};
let new_obj=new Circle();
new_obj.show();
new_obj.show();
new_obj.show();
/*1 2 3*/
}
//Getters/Setters defineProperties
if(1){
let Circle=function(){
let new_obj={};
Object.defineProperty(new_obj,"data",{
get:function(){
return "hello";
},
set:function(el){
console.log(el);
}
});
return new_obj;
};
let new_obj=Circle();
new_obj.data="qw";
//qw
console.log(new_obj.data);
//hello
}
//继承(inheritance)
//不同的类需要相同的属性或方法,使用继承解决
if(1){
let Circle=function(radius){
this.radius=radius;
this.draw=function(){
console.log('draw');
};
}
let circle= new Circle(2);
console.log(circle.__proto__.__proto__);
//{}
}
//Object.defineProperty()
if(1){
let person={name:"gaowanlu"};
Object.defineProperty(person,"name",{
writable:false,//不可写
enumerable:true,//可枚举
configurable:false,//不可配置(可不可删去)
});
person.name="opp";
delete person.name;
console.log(person);
}
//原型继承
if(1){
let Circle=function(){
this.draw=function(){
console.log('draw');
}
};
let circle_1=new Circle();
let circle_2=new Circle();
//circle_1 circle_2内都有一个实体的方法draw
//占用两个内存空间,如果Circle对象多了起来怎么办
let Car=function(){
this.money=1000000;
};
//给Car的父类添加方法
Car.prototype.draw=function(){
console.log("draw");
}
let car_1=new Car();
let car_2=new Car();
car_1.draw();
car_2.draw();
//draw draw
}
//子类父类方法可以互相调用
if(1){
let Cir=function(){
this.draw=function(){
console.log("draw");
//this.move();
}
}
Cir.prototype.move=function(){
console.log("move");
this.draw();
}
let new_obj=new Cir();
new_obj.move();
//move draw
}
//继承不等于拥有
//继承的是父级的引用,自然父级改变,子级继承的也会改变
//Object.keys()返回对象实体成员
//for in 所有成员、包括继承的东西
if(1){
let Cir=function(){
this.data=123;
};
Cir.prototype.name="gaowanlu";
let new_obj=new Cir();
console.log(Object.keys(new_obj));
//[ 'data' ]
for(let key in new_obj){
console.log(key);
}
//data
//name
//判断是不是对象内的实体
console.log(new_obj.hasOwnProperty("data"));//true
console.log(new_obj.hasOwnProperty("name"));//false
}
//创建自己的原型继承
if(1){
let Tesla=function(){
this.type="Tesla";
};
Tesla.prototype.show=function(){
console.log(this.type);
}
let Audi=function(){
this.type="Audi";
};
Audi.prototype.show=function(){//show属于类
console.log(this.type);
}
let car_1=new Tesla();
let car_2=new Audi();
car_1.show();//Tesla
car_2.show();//Audi
//我们会发现又出现问题了,这两个方法不是一样吗,能不能用一个来表示
console.log(car_1);
console.log(car_2);
//使用继承
Tesla=function(){
this.type="tesla"
};
Tesla.prototype.show=function(){
console.log(this.type);
}
Audi=function(){
this.type="audi";
};
//让Audi使用和Tesla一样的prototype
//Object.create()会返回一个和Tesla.prototype一样的对象
Audi.prototype=Object.create(Tesla.prototype);
//此时Audi.prototype内的constructor是Tesla的构造函数,我们要更改过来
Audi.prototype.constructor=Audi;
//现在可以使用
let nice_car=new Audi();
nice_car.show();//输出audi
}
//要记住继承的是prototype对象内的内容而不是自己定义的对象属性与方法
//上面show方法属于prototype type属性属于对象,type不可以继承
//每个对象的构造函数为class.prototype.constructor()
//let cir=new Circle(1);
//等价于 let cir=new class.prototype.constructor(1);
//prototype就是__prototype__
//使用父对象构造函数
if(1){
let CarColor=function(color){
this.color=color;
}
let Tesla=function(color){
CarColor.call(this,color);//调用父对象构造函数
this.type="Tesla";
};
let car=new Tesla("red");
console.log(car);
//输出 Tesla { color: 'red', type: 'Tesla' }
}
//方法重写(Method Overriding)
//在子类中重写一个基类定义的方法
if(1){
let extend=function(child,parent){
child.prototype=Object.create(parent.prototype);
child.prototype.constructor=child;
}
let CarColor=function(color){
this.color=color;
};
CarColor.prototype.ShowColor=function(){
console.log("red");
}
let Tesla=function(color){
CarColor.call(this,color);
this.type="tesla";
};
extend(Tesla,CarColor);
let my_car=new Tesla("blue");
my_car.ShowColor();
//输出"red"
//这不是我们想要的方法怎么办,方法重写
//重写需要在继承之后
Tesla.prototype.ShowColor=function(){
console.log(this.color);
};
my_car=new Tesla("yellow");
my_car.ShowColor();
//yes!!输出了 yellow
}
//多态
//一个多个子类继承一个父类的同一个方法
//但在,两个子类中使用有不同的效果
if(1){
let extend=function(child,parent){
child.prototype=Object.create(parent.prototype);
child.prototype.constructor=child;
};
let CarColor=function(){
this.color="red";
};
CarColor.prototype.ShowColor=function(){
console.log("red");
};
let Tesla=function(color){
this.type="tesla",
CarColor.call(this,color);
};
extend(Tesla,CarColor);
Tesla.prototype.ShowColor=function(){
console.log("blue tesla");
};
let Audi=function(color){
CarColor.call(this,color);
this.type="audi";
};
extend(Audi,CarColor);
Audi.prototype.ShowColor=function(){
console.log("black audi");
};
let array=[new Tesla(),new Audi()];
for(let car of array){//多态的好处
car.ShowColor();
}
/*输出
blue tesla
black audi*/
}
//谨慎使用继承,不会用就避免使用
//ES6 Classes相关语法
if(1){
//之前Tesla构造函数
let Tesla=function(color){
this.color=color;
this.speed="299km/s";
this.type="tesla";
this.showUser=function(){
console.log("gaowanlu");
};
};
//采用ES6语法写
class Tesla_class{
constructor(color){//构造函数
this.color=color;
this.speed="299km/s";
this.type="tesla";
}
//在构造函数constructor外写的东西属于prototype的内容
showUser(){
console.log("gaowanlu");
}
}
let car = new Tesla_class("red");
console.log(car);
//输出 Tesla_class { color: 'red', speed: '299km/s', type: 'tesla' }
console.log(typeof(Tesla_class));
//输出 function
//class只是皮,肉是function
//Hoisting
//两种声明class方式
if(1){
class via{
}
const yiu=class{
}
}
//static Methods(静态方法:只在类中有效)
let ff=class{
constructor(){
}
draw(){
}
static parse(){
}
};
ff.parse();//ff中有parse()
let obj=new ff();
//obj.parse(); obj中没有parse()
//对象私有成员
const _draw=Symbol();
let lua=class{
constructor(){
}
[_draw](){
console.log("私有");
}
};
//外部无法使用[_draw]()
//弱映射
const _name=new WeakMap();
const _showname=new WeakMap();
let didi=class{
constructor(){
_name.set(this,123456);
_showname.set(this,function(){
console.log("_showname");
});
}
get radius(){
return 1;
}
set radius(el){
console.log(el);
}
}
}
//ES6 继承
if(1){
class TeslaColor{
constructor(color){
this.color=color;
}
ShowColor(){
console.log(this.color);
}
};
class TTCar extends TeslaColor{
constructor(color){
super(color);//调用TeslaColor构造函数
}
}
}
//ES6 方法重写
if(1){
class GaoF{
move(){
console.log("GaoF");
}
}
class Fu extends GaoF{
move(){//直接重写
}
}
}
/*javascript函数式编程基础*/
function sayHello(){
return "hello world";
}
let result=sayHello();//函数调用
let fn=sayHello;//函数引用
console.log(fn());//hello world
//函数做返回值
function ee(){
return function(){
return "hello world";
}
}
console.log(ee()());//hello world
//高阶函数,传入参数为函数
let nnjfd=[1,2,3];
nnjfd=nnjfd.map(number=>number*2);
console.log(nnjfd);//[2,4,6]//箭头函数,与流水线化
input="JS";
trim=str=>str.trim();
wrapInDiv=str=>`<div>${str}</div>`;
toLowerCase=str=>str.toLowerCase();
result=wrapInDiv(toLowerCase(trim(input)));
console.log(result);//<div>js</div>
//当wrapInDiv(toLowerCase(trim(input)));功能越多,代码越来越多
//比较乱,怎么解决看起来好一些呢
let fp=require("lodash/fp");
transform=fp.compose(wrapInDiv,toLowerCase,trim);//何为一个函数,从右到左执行
//每个函数的返回值会成为下个函数的参数
console.log(transform(input));//<div>js</div>
transform=fp.pipe(trim,toLowerCase,wrapInDiv);//何为一个函数,从左到右执行
console.log(transform(input));//<div>js</div>
//柯里化
trim=str=>str.trim();
wrapInDiv=type=>str=>`<${type}>${str}<${type}>`;
/*
function(a){
return function(b){
return a+b;
}
}
*/
toLowerCase=str=>str.toLowerCase();
transform=fp.pipe(trim,toLowerCase,wrapInDiv("div"));
console.log(transform(input));//<div>js<div>//纯函数
//纯函数中不能使用随机值
//No random values
//no current date/time
//no global state
function isEligible(age){//it's not pure function
return age>minAge;
}
function isEligi(age,minAge){//it's pure function
return age>minAge;
}
//纯函数优点
/*Self-documenting Easily testable Concurrency Cacheable*///更新对象
const person={name:'John',adress:{city:'san francisco'}};
person.name='Mary';
//Error person={}
tempObject=Object.assign({},person,{name:'Bob',age:11});//将person对象内的内容复制到{} 再返回
console.log(tempObject);//{ name: 'Bob', adress: { city: 'san francisco' }, age: 11 }
//拆分操作符
tempObject={...person,a:'a',b:'b'};
console.log(tempObject);//{ name: 'Mary', adress: { city: 'san francisco' }, a: 'a', b: 'b' }
tempObject.adress.city='ppp';
console.log(person);//{ name: 'Mary', adress: { city: 'ppp' } }
//上面对象的拷贝都只是一种浅拷贝,拆分操作符与Object.assign都是
//如何深拷贝,手动使用...将adress拆分,重写city
tempObject={...person,adress:{...person.adress,city:'p'}};
tempObject.adress.city='ccc';
console.log(tempObject);//{ name: 'Mary', adress: { city: 'ccc' } }
console.log(person);//{ name: 'Mary', adress: { city: 'ppp' } };
//或者使用深拷贝库来解决问题//更新数组
numbers=[1,2,3];
index=numbers.indexOf(2);
//Adding
added=[
...numbers.slice(0,index),
4,
...numbers.slice(index)
];
console.log(added);//[ 1, 4, 2, 3 ]
//Removing
numbers=numbers.filter(n=>{
return n!==4;
});
console.log(numbers);//[1,2,3]
//Updating
updated=numbers.map(v=>{return v===2?20:v});
console.log(updated);//[ 1, 20, 3 ]
//不可变对象immutable库
const { Map } = require('immutable');
let book=Map({title:"Harry Potter"});
function publish(book){
return book.set("isPublished",true);
}
booked=publish(book);
console.log(book.toJS());//{ title: 'Harry Potter' }
console.log(booked.toJS());//{ title: 'Harry Potter', isPublished: true }
book={title:"Harry Potter"};
const {produce}=require("immer");
function publish1(book){
return produce(book,draftBook=>{
draftBook.isPublished=true;
});
}
temp=publish1(book);
console.log(book);//{ title: 'Harry Potter' }
console.log(temp);//{ title: 'Harry Potter', isPublished: true }
temp.title='OOPOP';
console.log(book);//{ title: 'Harry Potter' }
console.log(temp);//{ title: 'Harry Potter', isPublished: true }