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
functionfoo(){console.log(this.name)}varobj={name: 'carpe',foo: foo}varbar=obj.foo// this指向现在是bar /** 类似于 var bar = function foo() {}*/varname='diem'bar()// diem
varnickname='carpe'functionPerson(name){this.nickname=namethis.distractedGreeting=function(){setTimeout(function(){console.log("Hello, my name is "+this.nickname)},500)}}varperson=newPerson('hanzo')person.distractedGreeting()// carpe// 解析setTimeout是全局环境下执行,所以this指向window// 方法1.缓存thisthis.distractedGreeting=function(){letself=thissetTimeout(function(){console.log("Hello, my name is "+self.nickname)},500)}2.箭头函数this.distractedGreeting=function(){letself=thissetTimeout(()=>{console.log("Hello, my name is "+self.nickname)},500)}3.bindthis.distractedGreeting=function(){letself=thissetTimeout(function(){console.log("Hello, my name is "+self.nickname)}.bind(this),500)}
// 完整代码Function.prototype.bind2=function(context){if(typeofthis!=='function'){thrownewError("Function.prototype.bind - what is trying to be bound is not callable")}letself=thisletargs=Array.prototype.slice.call(arguments,1)letfNOP=function(){}letfBound=function(){letbindArgs=Array.prototype.slice.call(arguments)returnself.apply(thisinstanceoffNOP ? this : context,args.concat(bindArgs))}fNOP.prototype=this.prototypefBound.prototype=newfNOP()returnfBound}
new原理及实现
new运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例
function Car(color) {
this.color = color
}
Car.prototype.start = function() {
console.log(this.color + 'car start')
}
var car = new Car('red')
car.color // red 访问构造函数属性
car.start() // red car start 访问原型的属性
this指向
五种绑定方法
绑定规则
默认绑定
undefined
隐式绑定
隐式丢失
显式绑定
new绑定
箭头函数
总结
箭头函数
记住5要点
apply
,call
,bind
来直接修改(可以间接修改)function closure(){()=>{//code }}
,在此例中,我们通过改变封包环境closure.bind(another)()
,来改变箭头函数this的指向apply , call 使用场景
实现call
引子
call
在此做了两点:相当于:
第一步 绑定this, 立即执行,并删掉
第二步 处理参数
注意细节
this
传入进来的是null
或者undefined
,将用window
代替this
传入 基本类型,原生的call
会自动用Object()
转换完整版
手写apply
补充
这里假设
context
对象本身没有fn
属性,这样肯定不行,我们必须保证fn
属性的唯一性bind
bind返回的绑定函数也能使用
new操作符创建对象:这种行为就像把原函数当成构造器,提供的
this值被忽略,同时调用时的参数被提供给模拟函数。
bind
和apply
、call
的区别是前者返回一个绑定上下文的函数, 后则是直接执行函数上面的例子表示
bind
的特性this
场景1
bind的柯里化
bind
有柯里化,所以bind
本身也是闭包的一种使用场景模拟实现
bind
四个特性this
上述代码已完成四点功能,但bind还有一个特性
案例
在new的实现中会生成一个新的对象,这时候的this指向obj
注释1:
当作为构造函数时,this 指向实例,此时
this instanceof fNOP结果为
true,可以让实例获得来自绑定函数的值,即上例中实例会具有
habit属性。
注释2:
修改返回函数的
prototype为绑定函数的
prototype,实例就可以继承绑定函数的原型中的值,即上例中
obj可以获取到
bar原型上的
friend注释3:
上面实现中fNOP.prototype = this.prototype
有一个缺点,直接修改 fNOP 的时候,也会直接修改 `this.prototype,解决方案是用一个空对象作为中介,把
fBound.prototype赋值为空对象的实例(原型式继承).
这边可以直接使用ES5的
Object.create()方法生成一个新对象,不过 bind 和 Object.create()都是ES5方法
注意事项
如果调用bind的不是函数,这时候要抛出异常
new原理及实现
new
创建实例的2个特性模拟实现
当代码
new Car()
的时候实现第一步
new
返回一个新对象,通过obj._proto_ = Con.prototype
继承构造函数的原型,同时通过Cona.apply(obj, arguments)
调用父构造函数实现继承,获取构造函数上的属性构造函数返回值
构造函数返回值有如下三种情况:
return
, 即返回undefined
undefined
以外的基本类型完整版
The text was updated successfully, but these errors were encountered: