this的指向规则是什么
先说this不承诺指向什么吧,打破最初级的误解
-
this不指向函数的类对象。
-
this也不指向函数所在的词法作用域
this的绑定和函数声明的位置无关,只取决于调用的方式,展开来说这个调用方式是(函数调用位置,调用方法,传参)的组合。
具体而言,this的指向规则如下
-
rule1 函数栈帧在栈底的时候,this 指向全局对象。
-
rule2/3: 以对象属性方法的方式调用时,this指向所调用的对象。背后的原理是这种调用方式完成了this到对象的隐式绑定,但不要以为obj.f1的声明,能让函数在后续的调用中被绑定影响,声明只停留在函数地址的取值赋值上,最终还得看调用时,call time的绑定。es5 提供了bind函数,实现函数this与对象的硬绑定。
-
rule4: 函数的new式调用,会创建一个object ,bind到该函数,执行该函数,并在函数无其它返回时,返回该对象。
-
rule5:ES6的箭头函数的内的this,绑定于词法作用域的this,即完成了在其声明处的this的硬绑定。
上述的bind都只影响该函数运行时的this的取值,再次强调this和声明无关,函数内声明的this只要未走到运行时,都和bind的值无关。取决于其执行时所在的函数域的调用.
总结一下,对this的理解: this的取值,取决于调用位置,取决于调用方式。同时存在隐绑定,和箭头函数的词法域硬绑定,new的新对象绑定,三种需要识别的情况,其余则是bind式调用或默认绑定。
要想对this的取值明确,建议如下
-
完全坚持this风格,使用硬绑定包装函数(柯里化)
-
词法作用域优先,使用变量建立词法域的this的中介,替代this。
js中的对象,面向对象编程与原型。
什么是对象,如何定义,如果构造,如何使用。
基础知识,js有六大类型
-
string
-
number
-
boolean
-
null
-
undefined
-
object
对象有一些特殊子类型,例如函数,Function,Array,String: 对string的装包构造。Date, Error
对象提供对属性的配置,包括读写性,枚举可见性。
for in会遍历出所有 可遍历的属性,对于数组来说那些被add的属性也会混入,形成困恼,因此避免对数组定义可枚举的属性,或者使用forEach来遍历
js的的oo观是什么?js有真正oo的class吗?
直截了当的说吧,js没有真正oo的class,没有真正类的概念。
尽管可以使用mixin,以js的对象拷贝来模拟继承和重载。但这很难维护和读懂,在js中实践oo总体而言是得不偿失的。
js中使用原型观而不是oo观。
什么是原型
一个对象的引用属性,可以指向另一个对象,形成一个链结构,该链上的对象的可枚举属性会被in关键字和属性访问符查到。子对象的属性会优先被访问。
原型链上的属性访问规则
-
如果父节点有属性,而子节点没有,使用=运算符时,当且仅当父节点的writeable为真时,会在子节点创建属性。
-
其它情况,
-
1:父节点writeable为假,爆异常
-
2,父节点有同名setter,导致调用父节点的setter,子节点不创建对应属性。
更多情况应该是,在父节点没有的情况下,子节点安全创建,或者子节点使用define Property的方式创建。
原型观有什么用?
js放弃了oo的观念,类在js中不存在,但js使用了对象,原型链来支撑抽象。
一个函数对象会关联一个全局对象,作为函数对象的prototype属性,成为所有改函数的new式调用得到的新对象的原型,该对象还具有一个constructor属性指向函数对象本身, 该函数的孪生prototype 对象的prototype是null。
函数对象的prototype对象可以被写,这意味着,new式调用得到的对象。constructor === F 并不可靠。
对象的prototype的 get 和set的标准API
Object.getPrototypeOf
Object.setPrototypeOf
时刻提醒 function对象的prototype是个对象的属性,而不是其prototype
instanceof 运算符判断一个对象的原型链上是否包含了一个 函数的原型属性对象。
硬绑定不影响 instanceof操作符
bind构造的函数的原型指向原函数的原型属性,其本身的原型属性反而是null。
使用Object,create 构建原型链比 new f 好处要多,其一就是避免function容易让人迷惑的 ‘构造’, 奇怪的 ‘原型属性’
Promis 相比回调有什么优点
1.解决调用过早的问题。调用一定发生在下一个或者更晚的异步时机。
2,解决调用过晚的问题,什么意思,then添加的回调函数集,在promise调用 回调时,会按序全部立即(不回再拖到下一个异步时机)发生回调。
3。使用promise race 为回调设定超时处理。防止回调用不执行。
- 在promise决议时,被then注册的回调最多被执行一次,可以防止回调过多。
还提供了 Promise.reslove 便捷函数用来直接异步执行一个有参函数
promise all 和 race 提供and / or 的逻辑。
promise 保证了回调的异步,可多例, 必然单次调用,异常兜底,自动装包promise的机制,提高了异步编程的可信度。