javascript-函数
1.函数如果没有return语句会返回undefined
8.1.2函数表示
[3,2,1].sort(function(a,b){return a-b;};//函数作为另一个函数的参数
let tensquared=(function(x){return x*x;}(10));//立即执行
8.1.3 Arrow functions
使用=>区分参数和函数体,不使用function关键字定义函数,也不需要函数名
con sum=(x,y)=>{return x+y;};//x,y为参数,函数体返回x+y;
如果函数体只有一句return 语句,你可以省略return关键字。
const sum=(x,y)=>x+y;//省略了return关键字
如果只有一个参数,你可以省略函数参数的括号
const polynomial= x=>x*x +2*x+3;//省略了括号,且省略了return关键字
如果函数没有参数,需要用()
const constantFunc=()=>42;//没有参数,返回值恒为42
返回值是对象需要用括号包起来,否则无法区分函数体和对象。两者都是{}
const f=x=>{return {value:x};};//ok
const g=x=>({value:x}});//ok
const h=x=>{value:x};//error return nothing,企图返回键值对
const i=x=>{v:x,w:x}//试图返回对象,但没有{},报错。且语句语法是错误的。
调用高阶函数的传递
let filtered=[1,null,2,3].filter(x=>x!=null);
let squares=[1,2,3,4].map(x=>x*x);
this关键字
嵌套函数并不继承父函数的this的值。被调用的时候在非严格模式指向全局对象,严格模式则是undefined
let o={
m:function(){
let self=this;
this===o;//true
f();
function f(){
this===o;//false this是global或undefined
self===o;//true
}
}
}
ES6以后箭头函数会继承this
const f=()=>{
this===o;//true 和上段f()作用类似,但这里内部this函数指向了o
}
8.2.3构造器调用
当调用构造函数不传递参数时,可以省略()
例:
o=new Object();
o=new Object;
上述两句功能相同。
构造函数一般不使用return语句。他们一般初始化对象并隐式return。这种情况下,新对象就是返回值。如果构造函数显示使用return语句返回对象,那么它就会返回你return的对象值。如果构造函数只使用的return没有后跟对象,那么它会返回初始化过后的新对象。
8.2.4间接调用
函数也是对象。拥有方法,call(),apply(),调用他们会间接调用函数。8.7.4会详细介绍
8.2.5隐式调用
1.getter setter会隐式调用get set方法
2.对象用于字符串string类型的上下文,会调用toString()数字number上下文,会调用valueOf()
3.遍历对象会导致方法调用。第12章会详细讨论。
4. 14.5小节 tagged template lietral
5. Proxy object 14.7 小节
7.3函数参数,javascript传递参数不做类型检查。
传递参数的技巧
function getPropertyNames(o,a){
if(a===undefined)a=[];//当没有传递a时新建一个空数组
for(let proerty in o)a.push(property);
return a;
}
let o={x:1},p={y:2,z:3};
let a=getPropertyNames(o);//a==["x"]
getPropertyNames(p,a);//a==["x","y","z"]
或使用a=a||[];//短路
ES6后可以使用默认值
function getPropertyNames(o,a=[]){//a有默认值空数组
for(let proerty in o)a.push(property);
return a;
}
可以使用前一个值计算后一个参数值
const rectangle=(width,height=width*2)=>({width,height});//利用width计算height
rectange(1)//{width:1,height:2}
8.3.2剩余参数和数组长度
利用剩余参数实现返回最大值。
function max(first=-Infinity,...rest){
let maxValue=first;
for(let n of rest){
if(n>maxValue)
maxValue=n;
}
return maxValue;
}
max(1,100,10,2,3,100,4,5,6);//1000
rest是一个数组,可以为空,但不会是Undefined
这种函数被称为varargs。
8.3.3 Arguments 对象
在Es6之前,很多情况下会使用Arguments对象。下例实现最大值返回
function max(x){
let maxValue=-Infinity;
for(let i=0;i<argumets.length;i++){
if(arguments[i]>maxValue)maxValue=arguments[i];
return maxValue;
}
这种代码很难优化,现在不建议使用Arguments对象了。在严格模式中arguments被视为保留关键字,你不可以用它定义函数参数,本地变量。
7.3.5解构函数参数
需要传入的参数是数组,用[]表示
function vectorAdd([x1,y1],[x2,y2]){
return [x1+x2],[y1+y2];
}
vectorAdd([1,2],[3,4])
需要传入的参数是对象用{}表示
function vectorMultiply({x,y},scalar){
return {x:x*scalar,y:y*scalar};
}
vectorMultiply({x:1,y:2},2);
默认参数的情况,z为默认参数
function vectorMultiply({x,y,z=0},scalar){
return {x:x*scalar,y:y*scalar,z:z*scalar};
}
vectorMultiply({x:1,y:2},2);
8.7函数属性,方法,构造器
8.7.1length属性。只读,表示参数列表中的参数数量。如果有rest变量,不累加在长度中
8.7.2 name属性,函数名
8.7.3 prototype 属性,函数会继承prototype中的属性。
8.7.4 apply() call()//需进一步看资料理解
apply(),call()d的第一个参数是对象,如f.call(o);f.apply(o);
相当于执行
o.m=f;
o.m();
delete o.m;
如果需要传递参数
f.call(o,1,2);传送两个数,1,2
f.apply(o,[1,2]);必须使用数组进行参数传递
如果函数参数长度不定,apply()方法允许你传入一个数组长度不定的数组。
8.7.5 bind()方法。
bind()方法用于将函数f和对象o绑定,返回一个新函数。
function f(y){return this.x+y;}
let o={x:1};
let g=f.bind(o);
g(2);//3
let p={x:10,g};
p.g(2);//g和o绑定,p调用不会得到11,而是得到3
箭头函数不可以执行bind(),因为它会继承this属性。
8.8.3Partial Application of Functions page 216 看不懂