值传递
1.适用类型
- 基本数据类型
1.string,number,boolean,undefined, null. - 传参
- 深拷贝
- 实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>值传递和引用传递</title>
</head>
<body>
<script type="text/javascript">
//赋值
let a=1;
let b=2;
console.log("a=%d",b=%d",a,b");
//更新a
a=3;
console.log("a=%d,b=%d",a,b);
</script>
</body>
</html>
引用传递
1.适用类型
- 引用数据类型
1.Array, Function,object. - 浅拷贝
2.实例代码
3.传参<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>值传递和引用传递</title>
</head>
<body>
<script type="text/javascript">
let obj1={
a:1,
b:2,
}
console.log("obj1=%o",obj1);
let obj2=obj1;
console.log("obj2=%o",obj2);
console.log(obj1===obj2);
//更新obj1.
//对象使用点来访问内部成员.
obj1.a=4;
console.log("obj1=%o",obj1);console.log("obj2=%o",obj2);
</script>
</body>
</html>
1.实例代码
2.模板字面量<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>值传递和引用传递</title>
</head>
<body>
<script type="text/javascript">
const f1=function(x){
x=10;
};
let m=5;
//m是入参
f1(m);
console.log("m=%o",m);//5
//上述代码的简化.
const f1=(x)=>(x=10);
let m=5;
f1(m);
console.log("m=%o",m);
const f2=(x)=>(x.a=10);
let o={a:1,b:2};
f2(o);
console.log("0.a=",o.a);
</script>
</body>
</html>
1.组成部分- 字符串字面量
- 插值
- 实例代码
3.标签函数<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板字面量和标签函数</title>
</head>
<body>
<script type="text/javascript">
let name="赵老师";
// let str="hello"+name;//hello 赵老师(传统方式)
//运用${name}插值方式获取元素
let str=`hello ${name}`;
console.log(str)//hello 赵老师
//模板字面量将表达式和插值嵌入到字符串
let menus=['首页','导航','个人中心'];//menus[0],menus[1],menus[2]
//字符串字面量
let htmlStr=`
<nav>
<a href="">${menus[0]}</a>
<a href="">${menus[1]}</a>
<a href="">${menus[2]}</a>
</nav>
`;
console.log(htmlStr);
</script>
</body>
</html>
- 参数约定
- 第一个参数:所有字符串字面量组成的数组
- 第二个参数:插值组成的数组
2.实例代码
4.解构赋值<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标签函数</title>
</head>
<body>
<script type="text/javascript">
// a,b代表插值,strs代表字符串字面量
let sum=(strs,a,b)=>{
console.log(strs);
console.log(a,b);
}
let a=48;
let b=12;
sum `${a}+${b}=`;//60
//归并参数
let sum=(strs,...arr)=>{
console.log(strs);
console.log(arr);
}
let c=12;
sum `${a}+${b}+${c}=`;//72
</script>
</body>
</html>
- 对象解构
- 参数解构
1要求 - 等号左边要求与等号右边一样.
5.实例代码1
6.实例代码2<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组解构</title>
</head>
<body>
<script type="text/javascript">
let [a,b,c]=[1,2,3];
console.log(a,b,c);//123
let [a,b]=[1,2,3]
console.log(a,b,c)//c is undefined;
[a,b]=[1,2,3]
console.log(a,b)//1,2
[a,b,c="js"]=[1,2]
console.log(a,b,c)//1,2 js
[a,b,...c]=[1,2,3,4,5,6,7,8];
console.log(a,b,...c);//1,2,3,4,5,6,7,8
[,,,a,,,,]=[1,2,3,4,5,6,7,8]
console.log(a);//4
</script>
</body>
</html>
7.对象解构<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>传统的数字交换</title>
</head>
<body>
<script type="text/javascript">
//传统的数字交换
let x=1;
y=10;
t;
t=x;
t=y;
x=y;
console.log(x,y)//x=10,y=1
//简便方法是
let a=10;b=1;
[a,b]=[b,a]//a=1,b=10
</script>
</body>
</html>
8.数组传参<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>对象解构</title>
</head>
<body>
<script type="text/javascript">
let item={
id:10,
name:"小红"
};
let id=item.id;
let name=item.name;
console.log(id,name);//id:10,name:小红
//一致
//{id,name}={id:10,name:"小红"}
({id,name}={id:10,name:"电脑"});
console.log("id=%o,name=%o",id,name);//id:10,name:电脑
</script>
</body>
</html>
9.对象传参<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组传参</title>
</head>
<body>
<script type="text/javascript">
let sum=([a,b])=>a+b;
console.log(sum([1,2]));//3
</script>
</body>
</html>
10.bind, apply,call介绍<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>对象传参</title>
</head>
<body>
<script type="text/javascript">
let getUser=({name,email})=>[name,email];
console.log(getUser({name:"小红",email:"12@qq.X-UA-Compatible"}));
</script>
</body>
</html>
共同点:三种都可以改变this的指向。
不同点:- bind只绑定不执行。
2.call,apply,绑定后立即执行,但参数不一样。
3.call,参数是离散一个一个传入的。
4.apply参数以数组得形式统一传入。
实例演示:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组传参</title>
</head>
<body>
<script type="text/javascript">
function hello(name, name2){
//this:执行上下文,程序运行环境。
//this当前是全局window
this.name=name;
console.log(this)//window
}
hello("小明");
//使用bind()改变函数中this的指向。
const obj={
name:"小李",
};
//bind()只绑定不执行
let f=hello .bind(obj."admin");
console.log(f())//undefined
console.log(this)//name:admin
//如果函数中的this被重新绑定之后,要求立即执行用apply, call.
f=helo.call(obj,"小红");
console.log(this)//name:小红
hello.apply(obj,['小李','小红','小刘']);
console.log(this)//name:小李,小红,小刘
</script>
</body>
</html>
- 访问器属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>访问器属性</title>
</head>
<body>
<script type="text/javascript">
//对象成员:属性,方法
//属性:类似于变量
//方法:类似于函数
const product={
data:[
{id:1,name:"电脑",price:20000, num:1},
{id:2,name:"手机",price:10000, num:1},
{id:3,name:"idpan",price:20000, num:1},
{id:4,name:"电视机",price:20000, num:1},
],
//计算总金额
//方法
getAmounts:function(){
return this.data.reduce((t,c)=>(t+=c.price*c.num),0);
},
};
console.log("总金额=",product.getAmounts());
//将一个方法包装成一个属性,get是访问器属性的读操作
get total(){
return this.data.reduce((t,c)=>(t+=c.price*c.num),0)
}
//set 是访问器属性的写操作,
set serPrice(price){
this.data[1].price=price;
};
product.serPrice=8000;
console.log(product.data[1].price);//将改变product第一个产品的价格
//用属性的方式来获取总金额
console.log("总金额=",product.total);
</script>
</body>
</html>
- 访问器属性的优先级
3.作用域和闭包<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>访问器属性的优先级</title>
</head>
<body>
<script type="text/javascript">
let user={
data:{name},
get name(){
return this.data.name;
},
set name(v){
this .data.name=v;
},
};
//访问器属性的优先级高于同名的普通属性。
user.name="小六";
console.log(user.name);//name:小六
</script>
</body>
</html>
作用域的分类
1.函数作用域
2.块作用域
3.全局作用域<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组传参</title>
</head>
<body>
<script type="text/javascript">
//全局作用域对象是window
console.log(this)//window
//函数作用域
let site="我是全局变量"
function getSize(){
//site是声明在函数外部的全局变量
//在函数内部可以访问外部的变量,但是函数外部的不能访问内部的变量。
return size;
}
console.log(getSize());//我是全局变量
//块作用域
//用于if,while语句中
if(条件){
//满足条件的语句
};
while(条件){
//满足条件的语句
}
</script>
</body>
</html>
- 总结:函数作用域是一个查询的过程,先在自身查找要输出的变量,如果没有则一级一级往上查找,一直没有则返回undefined;它的查找过程构成了作用域链。var声明的变量不支持块作用域。
- 闭包
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>访问器属性</title>
</head>
<body>
<script type="text/javascript">
let c=100;
function sum(a,b){
return a+b+c;
}
console.log(sum(4,5));109
//上述产生了闭包
//通过sum()函数之外的c变量可以产生闭包
//c属于自由变量
</script>
</body>
</html>