详解JavaScript中操作符和表达式
一、一元操作符
1.delete操作符
delete操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放
语法:deleteexpression
delete操作符会从某个对象上移除指定属性。成功删除的时候回返回true,否则返回false
letEmployee={ age:28, name:'abc', designation:'developer' }; console.log(deleteEmployee.name);//returnstrue console.log(deleteEmployee.age);//returnstrue console.log(Employee);//{designation:"developer"}
2.typeof操作符
typeof操作符返回一个字符串,表示未经计算的操作数的类型
语法:typeofoperand;typeof(operand);
typeofNaN==='number'; typeofNumber(1)==='number'; typeof""==='string'; typeoftrue==='boolean'; typeofSymbol('foo')==='symbol'; typeofundefined==='undefined'; typeofnull==='object' typeof[1,2,4]==='object'; typeofnewBoolean(true)==='object'; typeofnewNumber(1)==='object'; typeofnewString("abc")==='object'; typeoffunction(){}==='function';
3.void运算符
void运算符对给定的表达式进行求值,然后返回undefined
语法:voidexpression
这个链接点击之后不会做任何事情,如果去掉void(), 点击之后整个页面会被替换成一个字符0。 chrome中即使
也没变化,firefox中会变成一个字符串0 点击这个链接会让页面背景变成绿色。
二、关系操作符
1.in运算符
如果指定的属性在指定的对象或其原型链中,则in运算符返回true
语法:propinobject
lettrees=newArray("redwood","bay","cedar","oak","maple"); console.log(0intrees);//返回true console.log(3intrees);//返回true console.log(6intrees);//返回false console.log("bay"intrees);//返回false(必须使用索引号,而不是数组元素的值) console.log("length"intrees);//返回true(length是一个数组属性)
2.instanceof运算符
instanceof运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性
语法:objectinstanceofconstructor
letsimpleStr="Thisisasimplestring"; letmyString=newString(); letnewStr=newString("Stringcreatedwithconstructor"); letmyDate=newDate(); letmyObj={}; simpleStrinstanceofString;//返回false,检查原型链会找到undefined myStringinstanceofString;//返回true newStrinstanceofString;//返回true myStringinstanceofObject;//返回true myDateinstanceofDate;//返回true myObjinstanceofObject;//返回true,尽管原型没有定义
三、表达式
1.this
在函数内部,this的值取决于函数被调用的方式。在严格模式下,this将保持他进入执行上下文时的值,所以下面的this将会默认为undefined
functionf2(){ "usestrict";//这里是严格模式 returnthis; } f2()===undefined;//true
当一个函数在其主体中使用this关键字时,可以通过使用函数继承自Function.prototype的call或apply方法将this值绑定到调用中的特定对象
functionadd(c,d){ returnthis.a+this.b+c+d; } leto={a:1,b:3}; //第一个参数是作为‘this'使用的对象 //后续参数作为参数传递给函数调用 add.call(o,5,7);//1+3+5+7=16
调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的
functionf(){ returnthis.a; } letg=f.bind({a:"azerty"}); console.log(g());//azerty leth=g.bind({a:'yoo'});//bind只生效一次! console.log(h());//azerty
在箭头函数中,this与封闭词法上下文的this保持一致。在全局代码中,它将被设置为全局对象
letglobalObject=this; letfoo=(()=>this); console.log(foo()===globalObject);//true
2.super
语法:
super([arguments]);//调用父对象/父类的构造函数
super.functionOnParent([arguments]);//调用父对象/父类上的方法
在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。super关键字也可以用来调用父对象上的函数
classHuman{ constructor(){} staticping(){ return'ping'; } } classComputerextendsHuman{ constructor(){} staticpingpong(){ returnsuper.ping()+'pong'; } } Computer.pingpong();//'pingpong'
3.new
new运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例
functionCar(){} car1=newCar() console.log(car1.color)//undefined Car.prototype.color=null console.log(car1.color)//null car1.color="black" console.log(car1.color)//black
4.展开语法
可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;还可以在构造字面量对象时,将对象表达式按key-value的方式展开
在函数调用时使用展开语法
functionmyFunction(x,y,z){} letargs=[0,1,2]; myFunction.apply(null,args); //展开语法 functionmyFunction(x,y,z){} letargs=[0,1,2]; myFunction(...args);
构造字面量数组时使用展开语法
letparts=['shoulders','knees']; letlyrics=['head',...parts,'and','toes']; //["head","shoulders","knees","and","toes"]
数组拷贝
letarr=[1,2,3]; letarr2=[...arr];//likearr.slice() arr2.push(4); //arr2此时变成[1,2,3,4] //arr不受影响
连接多个数组
letarr1=[0,1,2]; letarr2=[3,4,5]; //将arr2中所有元素附加到arr1后面并返回 letarr3=arr1.concat(arr2); //使用展开语法 letarr1=[0,1,2]; letarr2=[3,4,5]; letarr3=[...arr1,...arr2];
5.类表达式
类表达式是用来定义类的一种语法
letFoo=class{ constructor(){} bar(){ return"HelloWorld!"; } }; letinstance=newFoo(); instance.bar(); //"HelloWorld!"
6.函数表达式
function关键字可以用来在一个表达式中定义一个函数,你也可以使用Function构造函数和一个函数声明来定义函数
函数声明提升和函数表达式提升:JavaScript中的函数表达式没有提升,不像函数声明,你在定义函数表达式之前不能使用函数表达式
/*函数声明*/ foo();//"bar" functionfoo(){ console.log("bar"); } /*函数表达式*/ baz();//TypeError:bazisnotafunction letbaz=function(){ console.log("bar2"); };
7.function*表达式
function关键字可以在表达式内部定义一个生成器函数,function这种声明方式(function关键字后跟一个星号)会定义一个生成器函数(generatorfunction),它返回一个Generator对象
语法:function*name([param[,param[,...param]]]){statements}
function*idMaker(){ letindex=0; while(index<3) yieldindex++; } letgen=idMaker(); console.log(gen.next().value);//0 console.log(gen.next().value);//1 console.log(gen.next().value);//2 console.log(gen.next().value);//undefined
接收参数
function*idMaker(){ letindex=arguments[0]||0; while(true) yieldindex++; } letgen=idMaker(5); console.log(gen.next().value);//5 console.log(gen.next().value);//6
传递参数
function*createIterator(){ letfirst=yield1; letsecond=yieldfirst+2;//4+2 //first=4是next(4)将参数赋给上一条的 yieldsecond+3;//5+3 } letiterator=createIterator(); console.log(iterator.next());//"{value:1,done:false}" console.log(iterator.next(4));//"{value:6,done:false}" console.log(iterator.next(5));//"{value:8,done:false}" console.log(iterator.next());//"{value:undefined,done:true}"
表达式
letx=function*(y){ yieldy*y; };