批改状态:合格
老师批语:
解析:
值传递:通常用于原始类型数据的赋值,如string,number,bool
引用传递:通常用于引用类型数据的赋值,如object,array
值传递代码说明:
let a=2;let b=a; //将a的值赋给bconsole.log("a=%d,b=%d",a,b); //控制台输出 a=2,b=2a=3;console.log("a=%d,b=%d",a,b); //控制台输出 a=3,b=2
注: 原始类型的a发生改变,不影响b的值
值传递代码说明:
let obj1={a:1,b:2};let obj2=obj1;//以下现行代码都在控制台输出{a:1,b:2}console.log(obj1);console.log(obj2);//更新obj1obj1.a =10;console.log(obj1); //控制台输出{a:10,b:2}console.log(obj2); //控制台输出{a:10,b:2}
区别与联系:
值传递传递的是内存中存放的数据,把a的值赋给b,两个之间没有任何联系。
引用传递传递的是内存的地址,把a的值赋给b,相当于a和b指向同一个内存地址,当时内存地址中存放的数据发生改变,则a和b的值都会同步发生改变。
解析:解构赋值,目的是快速从集合数据(数组和对象)解构出独立变量,其实相当于给集合数据中的每个数据指定成一组key/value名值对。通过key就能快速的访问到value值。
通过设定好的key(a,b,c),就能访问到对应的value
数量一致
let [a,b,c] = [1,2,3];console.log(a,b,c);//控制台输出1,2,3
key值多,那没有对应value值的key就会显示为undefined
let [a,b,c,d] = [1,2,3];console.log(a,b,c,d);//控制台输出1,2,3,undefined//可以指定默认值的方式给上面的d赋值let [a,b,c,d=10] = [1,2,3];console.log(a,b,c,d);//控制台输出1,2,3,10
如果key值数量比数组长度小,那么按照顺序对应
let [a,b] = [1,2,3];console.log(a,b);//控制台输出1,2,数组中的3没有对应的key
如果想直接访问到数组的特定位置的value,如第三个,则前面两个可以用 , 来占位
let [,,c] = [1,2,3];console.log(c);//控制台输出3
对象解构前提:属性名与变量名必须一一对应,顺序无所谓
let {id,name,email} = {id:1,name="T-Mac",email="123@abc.com"}console.log(id,name,email);//输出:1,T-Mac,123@abc.com
当变量已经存在时,同名的属性名有可能会将已存在的变量覆盖,造成数据流失,此时可以通过起别名的方式来避免冲突。
let email="456@abc.com";let {id,name,email} = {id:1,name="T-Mac",email="123@abc.com"}console.log(email);//控制台输出123@abc.com,因为覆盖造成456@abc.com数据流失
起别名:
let email="456@abc.com";let {id,name,email:'Temail'} = {id:1,name="T-Mac",email="123@abc.com"}console.log(Temail);//控制台输出123@abc.comconsole.log(email);//控制台输出456@abc.com
call,apply,bind方法主要用来动态改变this指向的对象
以下代码是页面上的给页面上的button控件添加一下点击事件,正常情况下控制台上输出的name应该是空,因为button并没有指定name属性,此时this指向对象是button
<button>click</button>//以下是script代码document.querySelector("button").addEventListener("click",function(){console.log(this.name);console.log(this);});
应用bind()改写如下,此时this不再指向button,而是指向我们通过bind()方法传入的对象{name:”人与自然”}
document.querySelector("button").addEventListener("click",function(){console.log(this.name);console.log(this);}.bind({name:"人与自然"}));
bind()只返回一个函数声明,不会立即执行,与之不同的是call()和apply()会立即执行
公共代码:
function hello(name){this.name = name ;console.log(this.name);}const obj = {name:"admin",};//经典调用console.log(hello("朱老师")); //控制台输出朱老师,里面的this指定hello("朱老师")//将hello绑定到obj对象中,bind()不会马上执行,只返回一个函数声明,此时this指向被更改,指向obj对象{"天蓬老师"},let f = hello.bind(obj,"天蓬老师");console.log(f); //控制台输出f函数的源代码console.log(f());//此时f函数才会调用,输出"天蓬老师"//call/apply立即执行f = hello.call(obj,'灭绝师太');console.log(f); //正常函数时,此时控制台应该输出函数源代码,但是由于call/apply函数的特性,此时控制台已经直接输出:灭绝师太
call()和apply的区别在于参数类型不同,后面那个参数必须是一个数组
上面代码应用apply()改成如下:
f = hello.apply(obj,['灭绝师太']);console.log(f); //正常函数时,此时控制台应该输出函数源代码,但是由于call/apply函数的特性(会立即执行),此时控制台已经直接输出:灭绝师太
访问器属性本质是对象里面定义的一个方法,但是可以伪装成对象的一个属性来使用。实际使用时,应该以性情赋值的方式,不能以调用方法的格式。
示范代码:
const product = {data [{name = "电脑",price : 5000, num: 5},{name = "手机",price : 4000, num: 10},{name = "相机",price : 10000, num: 3},]//定义一个访问器属性(一个set方法)set setPrice(price){this.data[1].price = price ;}};////错误,控制台提示:product.setPrice is not a function。因为setPrice是一个访问器属性,不能以调用方法的形式 setPrice(9999)进行调用,面应该以属性赋值的方式来进行调用//product.setPrice(9999); //错误代码product.setPrice = 9999;console.log(product.data[1].price);//控制台输出9999
另外,这种访问器属性一旦与对象原有属性重名时,会存在优先级的问题。
let user = {name = "张无忌";//访问器属性name()与原有属性name重名get name(){return "杨过";}};console.log(user.name); //控制台输出 杨过
以上代码可以看出,当访问器属性与对象的原有属性重名时,访问器属性的优先级较高,但是尽量不要出现访问器属性与原有属性重名的情况。
多分支一般用于多元判断,最简单的应用就是分数评级,如
let score = 65;if( score < 60 ){console.log("不及格");} else if ( score >= 60 && score <80 ){console.log("及格且良好");}else if ( score >= 80 && score <=100 ){console.log("优秀");}//最终控制台输出及格且良好
if-else if -else 可以用于区间判断,但是switch只能用于严格匹配
let response = "success";switch (response.toLowerCase()){case "fail" :console.log("请求失败");break;case "success" :console.log("请求成功");break;default:console.log("未知错误");//默认分支后面不用添加break;}
三元运算一般用来解决双分支问题,非黑即白。如果条件判断为真,返回结果1,否则返回结果2
格式为: 条件判断?结果1 : 结果2;
示范代码:
console.log(score>60?"及格" : "不及格");
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号