发表日期: 2021-04-28 13:02:01 浏览次数:47
项城申请400电话费用【项城企业全国热线电话办理】项城开通400电话电信价格、项城微信公众号代运营外包托管、项城网店编辑装修美工、项城网站推广优化大概需要多少钱
项城,位于河南省东南部,周口市下辖县级市,居黄河冲积平原南部,淮河主要支流沙颍河中游。位于河南、安徽两省交界处,大广高速、宁洛高速在市区交汇,106国道和5条省道穿越全境,漯阜铁路连接京广、京九,沙颍河航运直通长江,是豫东南较佳的人流、物流、资金流、信息流交汇点。
2018年,全市生产总值完成339.91亿元,同比增长8.7% [1] 。
项城以味精、皮革、医药、纺织为支柱的工业体系,是中国最大的手工鞋生产基地、中国著名的莲花味精所在地,中西部通往长三角最近的水运城市。2011年荣获“中国最佳投资城市”、“中国十大发展潜力城市”称号。 [2] 2019年2月2日,被国家中医药管理局评为县级全国基层中医药工作先进单位。 [3] 2020年1月22日,被住房和城乡建设部命名为国家园林城市。 [4-5] 2020年2月13日,获得2019年度全国“平安农机”示范县称号。 [6]
JS函数进阶
这次的内容我会给大家详细介绍函数方面的内容
1.箭头函数:ES6新增的定义函数的方式,箭头函数是用来简化函数定义语法的。
- 箭头函数的语法: ()=>{}
()里面写形式参数,{}里面写函数体
var fun1=(a,b)=>{
console.log(a+b);
}
fun1(1,2);// 3
可以看到这样写的函数就相当于
function fun2(a,b) {
console.log(a+b);
}
fun2(1,2)//3
- 如果如果形参只有一个,形参外侧的小括号也可以省略,例如:
var fun3=a=>{
console.log(a);
}
fun3(1);//1
- 如果函数体中只有一句代码,并且代码的执行结果就是函数的返回值,函数体大括号可以省略,例如:
var fun4=a=>a;
console.log(fun4(5));//5
var fun5=(a,b)=>a+b;
console.log(fun5(5,1));//6
- 在箭头函数中,我们最需要注意的一点是:箭头函数不绑定this关键字,箭头函数中的this,指向函数定义位置的上下文this,请仔细看如下代码:
var count=5;
var objX={
count:10,
fun:()=>{
console.log(this.count);
}
}
objX.fun();//5
为什么是5?,首先全局作用域中定义了一个count=5,对象objX中定义了一个count=10,由于这里是箭头函数,里面的this会指向函数定义位置的上下文,在这里面就会指向objX这个对象,但是objX是一个对象不会产生作用域,就会指向全局作用域window(nodejs里为global),而count=5定义在全局作用域下面,所以输出5!
不使用箭头函数我们观察一下结果
var count=5;
var objX={
count:10,
fun:function() {
console.log(this.count);
}
}
objX.fun();//10
不使用箭头函数就会输出10,指向了这个对象。在后面我会详细给大家介绍各种不同调用方式的函数里面的this指向会有什么不同!
- 箭头函数不支持arguments,例如:
function sum1() {
return Array.from(arguments).reduce((x, y) => x + y, 0);
}
console.log(sum1(1, 2, 3,4));//10
let sum2 = () => {
return Array.from(arguments).reduce((x, y) => x + y, 0);
};
console.log(sum2(1,2,3,4));//报错
箭头函数支持剩余函数。 例如:
let sum3 = (...nums) => {
return nums.reduce((x, y) => x + y, 0);
};
console.log(sum3(1, 2, 3));// 6
2.函数的4种定义方式:
自定义函数(存在函数的提升,当函数一被定义就提升到顶层)
例如:
console.log(sum(1,2));//3
function sum(num1,num2){
return num1+num2;
};
console.log(sum(1,2));//3
这是我们最常见的函数定义方法,存在函数的提升,当我们自定义函数一旦声明就会提升到顶层!
匿名函数(不存在函数的提升,只有在定义函数语句之后调用才有效,否则报错)
例如:
console.log(fun(1,2));//报错
var fun=function (num1,num2){
return num1+num2;
};
console.log(fun(1,2));//3
这里声明fun函数之前就调用了fun函数,由于不存在函数的提升,所以会报错,只有在声明之后再使用。
构造函数( new Function(a,b,‘函数体’) ) 不存在函数提升
例如:
console.log(result(1,2));//报错
var result=new Function(
"num1",
"num2",
"return num1+num2;"
);
console.log(result(1,2));
Function构造函数前面的参数都为形式参数,最后一个参数始终为函数体!,如上面所示,除去最后一个参数都为形式参数,最后一个参数为函数体。
不存在函数提升,必须先声明后使用!
存在的问题:
1容易出错,不能智能感应
2.会被做2次解释,第一次是将它当成ECMAScript代码,第二次是解释传给构造函数的字符串,
不推荐大家使用这种方法
箭头函数(不存在函数提升)
箭头函数也是函数定义的方法 语法为()=>{},例如下面代码:
console.log(jiantou(1,2));//报错
var jiantou=(a,b)=>a+b;
console.log(jiantou(1,2));
3.函数arguments属性
一个类数组对象(但不是 Array 的实例),因此可以使用中括号语法访问其中的元素。例如:
function fun(a,b,c) {
console.log(arguments instanceof Array);
console.log(arguments);
for(let i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
}
fun(1,2,3)
请看结果,arguments不是一个Array实例,是一个类数组对象,可以用arguments[0]等方法访问里面的数据
在函数体里,arguments.length表示传入函数实参的个数,而函数本身的length属性是刻度的,它代表函数声明的实际参数的数量,例如:
function fn(a,b){
console.log(arguments instanceof Array);//false
console.log(arguments instanceof Object);//true
console.log(arguments);
console.log(arguments.length);//5
console.log(fn.length);//2
console.log(arguments.callee.length);//引用当前函数对象的length. 2
}
fn(1,2,3,4,5);
主要的是arguments属性可以表示实际传入函数参数的个数,函数自带length属性表示函数定义的形参个数。
4.函数参数问题
- 函数的参数传递 例如:
function test(x,y='world'){
console.log(x,y);
}
function test1(x,y){
console.log(x,y);
}
test('hello');//hello world
test('hello','hello');//hello hello
test1('hello')//hello undefined
test1()//undefined undefined
请大家细品,如果形参里初始化了,不给这个形参传递值,这个形参就会输出初始化的值,如果给了这个形参传递值,这个形参就会使用传递过去的值。
如果形参没有初始化也没有传递值就会输出undefined
- 函数的参数的作用域 例如:
let x='world';
function test2(z,y=x){
console.log(z,y);
}
test2('hello');//hello world
test2();//undefined world
//在函数参数里面y=x,x找不到向外面找。找到x的值
//
function test3(x,y=x){
console.log(x,y);
}
test3('hello');//hello hello
test3();//undefiend undefiend
//在函数里有x,y会找参数里面的x的值
请看test2函数 形参y=x,x的值在形参里没有,就会找函数外面x的值输出!
请看test3函数 形参里有x了,如果不给这个x赋值就会输出undefined,此刻y=x,y找到了x的值为undefined,所以y也为undefined,可以理解为一个就近原则,那里的x的值比较近,就去调用那里的x的值!
- 函数参数(…arg),这是个收集参数(剩余参数),写了这个收集参数后面不能再写其他参数! 例如:
function test4(...arg){
console.log(arg);
console.log(arg instanceof Array);
};
test4('1','2',3,'tx');//['1','2',3,'tx'] true
console.log('a',...[1,2,3]);//把数组拆分
//a 1 2 3
请大家细品,在函数参数里面写剩余参数,就会把接收到的参数变成一个数组,但是在输出语句中写剩余参数,就会把数组拆开!!!
请再看一个实例:
function sum2(name,...scores){
let r=scores.reduce((x,y)=>x+y,0);
console.log(scores);
console.log(`${name}总分为:${r}.`);
};
sum2('tx',10,10,10);
//输出[10, 10, 10]
//tx总分为:30.
相信大家都明白剩余参数的用法了!
5.函数的6种调用方式的this指向问题
- 自定义函数的this指向 例如:
function f1(){
console.log('写代码');
console.log(this);//指向window
};
f1();//写代码 window
自定义函数里面的this 指向window全局
对象里面的函数的this指向,例如:
var obj={
id:1,
f2:function(){
console.log('写代码');
console.log(this);//指向这个对象
}
};
obj.f2();//写代码 obj
对象里面的函数this 指向的是这个对象,但是对象里面的函数如果写出箭头函数就会指向全局,我们在前面已经看见过
- 构造函数以及原型的this指向,例如
function myFriend(name,age){
this.name=name;
this.age=age;
this.favoriteSport=function(){
console.log('我喜欢打篮球');
console.log(this);//指向了利用这个构造函数创造的实例对象
}
};
myFriend.prototype={
sing(){
console.log('i can sing');
console.log(this);//构造函数原型里面的this也指向了这个构造函数创造的实例对象
},
constructor:myFriend
};
myFriend.prototype.__proto__={
dance(){
console.log('i can dance');
console.log(this);//构造函数原型里面的this也指向了这个构造函数创造的实例对象
},
constructor:myFriend.prototype
};
var tx=new myFriend('tx',20);
tx.favoriteSport();
tx.sing();
tx.dance();
结果为
大家可以知道了,构造函数以及原型对象里面的this都会指向这个构造函数实例化对象,简单来说就是用这个构造函数创造的实例对象,谁调用了这个方法,这个方法里的this就指向谁!
如果大家有一点不清楚原型的话可以看看我之前的博客,希望大家多和我沟通交流!
- 绑定事件的函数的this指向 例如:
var body=document.querySelector('body');
var btn=document.createElement('button');
btn.innerHTML='按钮';
body.appendChild(btn);
btn.onclick=function(){
console.log('我按下了按钮');
console.log(this);//this指向这个函数的调用者
};
这里的this会指向这个函数的调用者,也就是这个按钮!
- 定时器函数的this 指向 例如:
setInterval(() => {
console.log('定时器调用了');
console.log(this);//指向window
}, 5000);
定时器函数里面的this会指向window
- 立即执行函数的this指向 例如:
(function(num1,num2){
console.log(num1+num2);
console.log(this);//还是指向window
})(1,2);
立即执行函数里面的this依旧会指向window
6. call()改变函数内的this指向
call(this,par,par)可以调用一个对象,也可以改变函数内的this指向,第一个参数为要改变的this的指向,后面的为参数!
例如:
var o={
name:'tx'
};
function fn(a,b){
console.log(this);
console.log(a+b);
}
fn(1,2);//3
fn.call(1,2);//Number{1} NaN
fn.call(o,1,2);//第一个参数为改变的this指向,后面的为参数
第一个参数始终为指向,如果就写一个数字1 就指向数值对象
call的主要作用为继承 例如:
function Father(uname,age,sex){
this.uname=uname;
this.age=age;
this.sex=sex;
}
function Son(uname,age,sex){
Father.call(this,uname,age,sex)
//调用Father函数,用call把Father函数里面的this改为son里面的this
}
var son=new Son('tx','20','male');
console.log(son);
可以用call来继承
7.apply改变函数的this指向
- apply(thisArg,[argsArray])调用函数的方法,改变函数的this指向,第一个参数为要改变的this指向,第二个为传递的值,必须包含在数组
例如:
var o1={
name:'tn',
};
function fn1(name,age){
console.log(this);
console.log(name,age);
};
fn1();
fn1.apply();
fn1.apply(o1);
//apply的参数必须写成数组的形式
// fn1.apply(o1,'tx',20);//报错
fn1.apply(o1,['tx',20]);
基本上和call用法一致,就是要用数值的形式传递参数
apply的主要用法是利用apply运用数学对象方法
var arr=[1,2,3,99];
console.log(Math.max(1,2));//2
console.log(Math.max.apply(Math,arr));//99
这样更方便调用数学的方法!
8.bind()方法不会调用函数,但是能改变函数内部的this指向
bind(thisArg,arg1,arg2,…)
thisArg:在函数运行时指定的this
arg1,arg2:传递的其他参数
返回由指定的this值和初始化参数改造的原函数拷贝
bind()绑定后,不能再利用call,apply
例如:
var o2={
name:'tx',
};
function f3(a,b){
console.log(this);
console.log(a+b);
};
f3.bind(o2);//不输出 相当于一个新函数
var f=f3.bind(o2)
f(1,2);
输出这个结果,bind()不会调用原来的函数 可以改变原来函数内部的this指向,返回的是原函数改变this之后产生的新函数
引用场景:如果有的函数我们不需要立即调用,又想改变这个函数内部的this指向,之前的call和apply都是会立即调用的
在这里我给大家介绍一下偏函数
偏函数 ,固定一个函数的一个或者多个参数,
返回一个新的函数,这个函数用于接收剩余的参数
例如:
//给函数固定一个参数 生成新函数。新函数继续接收其他参数
let sum=function(x,y){
console.log(x+y);
console.log(x);
console.log(y);
};
let succ=sum.bind(null,1);//null不改变指向 1传x
succ(2)//2传入y
9.回调函数
被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。 例如:
let data={
x:10,
y:20,
show:function(how){
how(this.x,this.y);
},
};
data.show(function(a,b){
console.log(`${a},${b}`);
});
data.show((a,b)=>{
console.log(`${a}->${b}`);
});
如何理解,首先下面2个函数都是作为实参传递给一个函数,并在该外部函数内被调用,用以来完成某些任务,这就是回调函数
在data对象里写了一个show方法,但是show方法的表示不明确,就可以用另一个函数当作形参传递给show方法来调用,例如数组里的foreach函数也是一个回调函数
10.函数闭包
闭包的主要作用:延伸了变量的作用范围
要认识闭包,我们首要要知道:变量作用域分为全局作用域和局部作用域,函数内部可以使用全局变量,函数外部不能使用局部变量,当函数执行完毕,这个函数作用域的局部变量会被销毁。
我们还要知道,ActiveObject,当调用一个函数时会,会生成ActiveObject对象保存局部变量,当函数调用结束就会销毁ActiveObject对象
- 闭包的实质:可以理解为调用了局部作用域的变量,实质也就是利用另外一个函数的ActiveObject保存了之前函数的ActiveObject对象来保存之前函数的局部变量。
闭包的概念:指有权访问另一个函数作用域中变量的函数一个作用域可以访问宁一个函数内部的局部变量
我会给大家详细介绍闭包!
例如:
function f1(num1,num2){
var result=0
result=num1+num2;
console.log(result);
};
f1(1,2)
// console.log(result); 报错 没有定义
这里一定是报错的,调用f1函数会生成 ActiveObject对象来保存result这个局部变量,当调用结束就会销毁掉ActiveObject对象,我们就得不到result这个局部变量!
但是我们可以利用闭包来得到局部变量!
例如:
function fn(){
var num=10;
function fun(){
console.log(num);
//在fun这个函数内部访问了fn的局部变量
//产生了闭包
//fun这个函数作用域访问了宁外一个函数fn里的局部变量num
}
fun();
}
fn();// 10
这就是闭包 实际上就是当调用 fn函数是生成ActiveObject(1)对象来保存局部变量 num的值,然后又调用 fun函数,fun函数也会生成ActiveObject(2)对象,这个ActiveObject(2)相当于引用了ActiveObject(1),就能保存ActiveObject(1)里面的局部变量值!
ActiveObject对象要存在引用必须有函数嵌套的存在!!!!
例如:
var scope="globel scope";
function checkscope(){
var scope="loacl scope";
//当调用这个函数 生成Ao(x)保存局部变量
function f(){
return scope;
//当调用这个函数生成Ao保存局部变量
}
return f;//f为函数对象 对象当然存在Ao引用 相当于Ao引用了Ao(x) 就可以获取Ao(x)的局部变量
//如果不存在嵌套的函数,没有其他引用指向这个绑定对象,它就会被当作拉基回收
//如果存在嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象。
//最重要的是 对于上面这个情况:
//如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,
//这时就会有一个外部引用指向这个嵌套的函数。
//Ao它就不会被当做垃圾回收,并且它所指向的变量绑定对象也不会被当做垃圾回收。
}
var ff=checkscope();//函数调用结束,不存在局部变量,但是闭包让局部变量保留下来
//ff变相于 引用了Ao Ao保存了局部变量 Ao在函数调用结束后就不会被删除
//ff为一个函数对象 存在Ao引用Ao(x);
console.log(ff());//local scope;
}
//它们可以获取出局部变量,一直保存下去,存在闭包
大概就是这个意思,如果不存在函数嵌套,当调用函数生成的AO就会被当场垃圾删除掉!
项城申请400电话费用【项城企业全国热线电话办理】项城开通400电话电信价格、项城微信公众号代运营外包托管、项城网店编辑装修美工、项城网站推广优化大概需要多少钱
备案号: 苏ICP备11067224号
CopyRight © 2011 书生商友信息科技 All Right Reserved
24小时服务热线:400-111-6878 E-MAIL:1120768800@qq.com QQ:1120768800
网址: https://www.768800.com 网站建设:上往建站
关键词: 网站建设| 域名邮箱| 服务器空间| 网站推广| 上往建站| 网站制作| 网站设计| 域名注册| 网络营销| 网站维护|
企业邮箱| 虚拟主机| 网络建站| 网站服务| 网页设计| 网店美工设计| 网站定制| 企业建站| 网站设计制作| 网页制作公司|
400电话办理| 书生商友软件| 葬花网| 调温纤维| 海洋馆运营维护| 北京保安公司| 殡仪馆服务| 殡葬服务| 昌平殡葬| 朝阳殡葬|
欢迎您免费咨询,请填写以下信息,我们收到后会尽快与您联系
服务热线:400-111-6878