You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function_new(constructor, ...arg){// ① 创建一个新的空对象 objconstobj={};// ② 将新对象的的原型指向当前函数的原型obj.__proto__=constructor.prototype;// ③ 新创建的对象绑定到当前this上constresult=constructor.apply(obj,arg);// ④ 如果没有返回其他对象,就返回 obj,否则返回其他对象returntypeofresult==='object' ? result : obj;}functionFoo(name){this.name=name;}varluckyStar=_new(Foo,'luckyStar');luckyStar.name;//luckyStar
箭头函数调用
箭头函数中其实没有 this 绑定,因为箭头函数中this指向函数所在的所用域。箭头函数不能作为构造函数
导读
this
记得差不多在两年多之前写过一篇文章 两句话理解js中的this,当时总结的两句话原话是这样的:
{}
构成作用域,对象的{}
以及if(){}
都不构成作用域;当时对this的内部原理什么的都理解的不是很深刻,就只能凭借遇到很多坑之后,总结了出了那时候自己用来判断的标准。这里会再次略微深入的说一下。思路还是围绕上面总结的那两句话。
普通函数调用
foo()直接调用非严格模式下是this是指向 window上的,严格模式 this 指向的是undefined;
位置①,obj.foo(),是obj通过
.
运算符调用了 foo(),所以指向的值 obj。位置②,是把 obj.foo赋值给了 bar,实际上是把 foo函数赋值给了bar, bar() 调用的时候,没有调用者,所以使用的是默认绑定规则。
位置③,是把 obj.foo赋值给了 setTimeout,实际上调用的还是 foo函数,调用的时候,没有调用者,所以使用的是默认绑定规则。
位置②和位置 位置③ 的一定要注意。
使用 call,apply可以显式修改 this的指向,下面会详细介绍该部分。
要解释上面的结果就要从 new 的过程说起了
箭头函数调用
箭头函数中其实没有 this 绑定,因为箭头函数中this指向函数所在的所用域。箭头函数不能作为构造函数
call,apply,bind
call,apply,bind 这三个函数是 Function原型上的方法
Function.prototype.call()
,Function.prototype.apply
,Function.prototype.bind()
,所有的函数都是Funciton
的实例,因此所有的函数可以调用call,apply,bind 这三个方法。call,apply,bind 在用法上的异同
相同点:
call,apply,bind 这三个方法的第一个参数,都是this。如果你使用的时候不关心 this是谁的话,可以直接设置为 null
不同点:
但是有了 ES6引入的
...
展开运算符,其实很多情况下使用 call和apply没有什么太大的区别。举个例子,找到数组中最大的值
Math.max
是数字的方法,数组上并没有,但是我们可以通过 call, apply 来使用Math.max
方法来计算当前数组的最大值。手写 call,apply,bind
实现一个call:
实现一个apply
过程很call类似,只是参数不同,不再赘述
实现一个bind
MDN上的解释:bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
call 和 apply 的用途
call
let domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
apply
let max = Math.max.apply(null, array);
Array.prototype.push.apply(arr1, arr2);
重要参考
The text was updated successfully, but these errors were encountered: