赞
踩
目录
1. 箭头函数不能作为构造函数,而匿名函数可以作为构造函数。
(7)箭头函数不绑定arguments,取而代之用rest参数…解决
2. 隐式绑定规则:谁调用this就指向谁(参数赋值导致隐式丢失)
3. 显示绑定:call、apply、bind(用来绑定this指向)
1. ES6 的箭头函数和以前的普通函数的区别?
2. 箭头函数可以作为构造函数吗?为什么不能作为构造函数呢?
3. 箭头函数没有原型对象?
1. 箭头函数(箭头函数表达式**的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。)
this永远来自
其上下文的 this;
call(), bind(), apply();
2.
普通函数的
this
指向调用它的那个对象
使用方法:
其中()内是要带入的参数,{}内是要执行的语句。
定义:
箭头函数是函数式编程的一种体现,函数式编程将更多的关注点放在输入和输出的关系,省去了过程的一些因素,
因此箭头函数中没有自己的this,arguments,new target(ES6)和 super(ES6)。
箭头函数相当于匿名函数,因此不能使用new来作为构造函数使用。
三种定义方式:{} 、()、不加括号
总结1:
普通函数的this总是指向它的直接调用者。
在严格模式下,没找到直接调用者,则函数中的this是undefined。
在默认模式下(非严格模式),没找到直接调用者,则函数中的this指向window。
例如:
总结2:
对于方法(即通过对象调用了该函数),普通函数中的this总是指向它的调用者。
例如:
你可能会认为此时的输出应该为1,但是结果却是undefined。因为此时this的指向是全局的window对象。
解决方法1:
在setTimeout函数的外部,也就是上层函数foo内部通过将this值(this指向当前的对象)赋给一个临时变量来实现。
解决方法2:
通过bind()来绑定this。
箭头函数的 this
绑定是无法通过 call
、apply
、bind
被修改的,且因为箭头函数没有构造函数 constructor
,所以也不可以使用 new
调用,即不能作为构造函数
普通函数:在非严格模式下,默认绑定的this指向全局对象window;严格模式下this指向undefined
箭头函数:严格模式和非严格模式下它的this都会指向全局对象window
准确来说,箭头函数中没有this,箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁。
示例中,箭头函数的this指向,等于 其外层函数fn的this指向,即obj1
(函数fn的返回值为箭头函数,并赋值给bar,因此bar指向的是箭头函数,故bar.call(obj2)不能修改箭头函数的this指向)
一旦箭头函数的this绑定成功,也无法被再次修改(this始终指向其父级作用域中的this。任何方法都改变不了其指向,如call(), bind(), apply()。)
解决:
可以修改外层函数this指向达到间接修改箭头函数this的目的。
例如:
1)new执行过程:
- function Person() {
- var this = { //1、this 执行新的空对象
- __proto__: Person.prototype
- }
- this.name = name //2、给新对象添加属性和方法
- this.age = age
-
- return this //3、返回新对象
- }
-
- var person = new Person()
-
2)箭头函数:
箭头函数没有构造函数 constructor。
由于箭头函数没有自己的this,它的this来自上级作用域。并且不能通过修改箭头函数的this(只能通过修改其上级作用域的this进行改变)。
因此我们不能通过new来改变箭头函数Person的this指向,其指向仍为window,故箭头函数不能作为构造函数。
3)匿名函数:
匿名函数可以通过new修改其this指向,因此可以作为构造函数。
每一个函数都有一个arguments对象,用于访问未知或可变的函数参数,通常我们把它当作数组使用,
但它却不是数组,不能对arguments对象使用其他JavaScript数组方法,如pop,push,slice等。是对象类型
例1 普通函数:arguments存放了传入的实参
例1 箭头函数:报错
1)定义:
ECMAScript 6引入了一个新功能,Rest参数(扩展运算符...):
它表示一个未知数量的参数作为函数中的一个数组。它不仅将额外的参数表示为数组,还解决了arguments对象的许多问题。
如果最后命名的函数参数以…(三个点)作为前缀,那么它将成为函数的rest参数。
2)优势:
JavaScript函数的rest参数是纯JavaScript数组。
…a(其中a可以随意命名)是函数add的rest参数,因为它是唯一的命名参数,且也以…(三个点)作为前缀。
由于rest参数是JavaScript数组,所以你可以对rest参数a执行诸如push,pop等操作
3)注意:
rest必须是函数的最后一位参数;
函数的length属性,不包括 rest 参数;
箭头函数和普通函数都可以使用。
更加灵活,接收参数的数量完全自定义。
可读性更好,参数都是在函数括号中定义的,不会突然出现一个arguments,以前刚见到的时候,真的好奇怪了!
rest是一个真正的数组,可以使用数组的API。
主要看函数执行时的this
指向window,即this和window指向的是同一个对象
1.1 全局中:
console.log(this === window); // true
1.2 函数的独立调用(this默认指向window):
默认是挂载到window上的,
test() 相当于 window.test()
2.1 简单的方法调用 this指向
2.2 含有嵌套函数的this指向
每一个函数在执行时都会有自身的不同的this(他们的this指向是否相等,是由函数的执行方式决定的)(函数如果不执行,函数中的this没有任何意义),
所以下面例子中这两个函数的this不同(只需要看这两个函数的调用方式)
2.3 obj.foo()()的this指向(有返回函数)
2.4 变量赋值(赋值导致隐式丢失,即转化为了独立调用)
将obj.foo赋值给bar,调用bar() 。this指向window
2.5 参数赋值
obj.foo 表示函数foo =》 bar(obj.foo)相当于 bar(foo) =》 在函数bar中调用函数foo() ,独立调用 =》 故函数foo的this指向window
2.6 父函数有能力决定子函数的this指向
当函数为参数时,这个参数为回调函数
父函数指定子函数的this指向
1. 四种调用方式,分别调用foo函数(call、apply、bind 传参的方式不同)
其中call、apply、bind 参数中的obj:表示绑定的this指向
2.
3. null 和 undefined 不能作为this指向,如果作为this指向,则绑定失败,默认this指向为window。
例如:
1. new一个构造器,主要有三步:
• 创建一个空对象,将它的引用赋给 this(即this指向这个新对象),继承函数的原型。
• 通过 this 将属性和方法添加至这个对象(执行构造函数中的代码)
• 最后返回 this 指向的新对象,也就是实例(如果没有手动返回其他的对象)
相当于下面过程:
2. new 绑定
构造调用创建了一个新对象echo,而在函数体内,this将指向新对象echo上(可以抽象理解为新对象就是this)。
3. 用new创建person对象实例
结果说明了:用new的创建实例,构造函数作用域赋给了person1(通过构造函数的this指针),所以window。sayname自然就会提示错误。
- var person1=new Person("yyh","24","web前端")
-
- person1.sayname();//弹出对话框,显示“yyh” (sayname是Person对象中的方法)
-
- window.sayname()//提示错误,对象不支持此方法
4. 将构造函数作为普通函数来调用
结果说明了:不使用new创建构造函数的实例时,this指向的是全局作用域即window对象,所以window.sayname()显示的就是yyh2。可以说明Person的属性和方法都被添加到了window对象。
- Person("yyh2","25","web前端")
-
- window.sayname();//显示“yyh2”
-
- Person.sayname();//提示错误;
5. 在另外一个对象的作用域中调用(修改this指向)
call函数是指在对象0的作用域中调用Person函数,即绑定Person函数的this指向为o。
- var o=new Object();
- Person.call(o,"yyh2","25","web前端");
- o.sayname();//也显示yyh2
6. 构造函数也是函数。与函数的区别在哪里呢?很显然在于调用它们的方式不同。
任何函数,只要通过new操作符来调用,那么他就可以作为构造函数
任何函数,如果不通过new操作符来调用,他跟普通的函数没有区别
(1)箭头函数不能作为构造函数,不能使用new(箭头函数没有构造函数 constructor
)。
(2)箭头函数不绑定arguments,取而代之用rest参数...解决。
(3)this的作用域不同,箭头函数不绑定this,会捕获其外层第一个普通函数的this值,作为自己的this值。
(4)箭头函数本身的this指向不能改变,但可以修改它要继承的对象的this。
(5)箭头函数没有原型属性,所以箭头函数本身没有this。
(6)箭头函数不能当做Generator函数,不能使用yield关键字。(下面链接详细介绍了Generator函数)
https://blog.csdn.net/fu983531588/article/details/89482179?utm_source=app&app_version=4.6.1
(7)箭头函数不支持new.target(new.target是ES6新引入的属性,用于确定构造函数是否为new调用的)
(8)箭头函数不支持重命名函数参数,普通函数的函数参数支持重命名
(9)箭头函数相对于普通函数语法更简洁优雅
箭头函数一条语句返回对象字面量,需要加括号
2. 箭头函数在参数和箭头之间不能换行
3. 箭头函数的解析顺序相对||靠前
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。