Open yygmind opened 5 years ago
没看到Con前面的var,还以为写错了,哈哈,仔细一看,上面一行最后面还有个逗号哟
// 获得构造函数,arguments中去除第一个参数 Con = [].shift.call(arguments);
"去除" 应为 "取出"
这里会给新手造成误导
有个小问题,即使采用了第二版书写方式,如果在构造函数中仍然返回了一个 {name : name } , 那这个时候,实例仍无法访问原型属性,此时该怎么办呢?
@Maozc 手动将实例化对象的proto关联到构造函数的prototype就可以了:
function Foo(a, b){ const obj = {} this.a = a obj.b = b return obj } Foo.prototype.cat = function(){ console.log('qqqq') }
var aaa = new Foo(1, 2) aaa.proto = Foo.prototype aaa.cat()
定义
举个栗子
可以看出
new
创建的实例有以下 2 个特性注意点
ES6新增
symbol
类型,不可以使用new Symbol()
,因为symbol
是基本数据类型,每个从Symbol()
返回的symbol
值都是唯一的。模拟实现
当代码
new Foo(...)
执行时,会发生以下事情:Foo.prototype
的新对象被创建。Foo
,并将this
绑定到新创建的对象。new Foo
等同于new Foo()
,也就是没有指定参数列表,Foo
不带任何参数调用的情况。new
表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。模拟实现第一步
new
是关键词,不可以直接覆盖。这里使用create
来模拟实现new
的效果。new
返回一个新对象,通过obj.__proto__ = Con.prototype
继承构造函数的原型,同时通过Con.apply(obj, arguments)
调用父构造函数实现继承,获取构造函数上的属性(【进阶3-3期】)。实现代码如下
测试一下
完美!
不熟悉
apply / call
的点击查看:【进阶3-3期】深度解析 call 和 apply 原理、使用场景及实现不熟悉继承的点击查看:JavaScript常用八种继承方案
模拟实现第二步
上面的代码已经实现了 80%,现在继续优化。
构造函数返回值有如下三种情况:
return
,即返回undefined
undefined
以外的基本类型情况1:返回一个对象
实例
car
中只能访问到返回对象中的属性。情况2:没有
return
,即返回undefined
实例
car
中只能访问到构造函数中的属性,和情况1完全相反。情况3:返回
undefined
以外的基本类型实例
car
中只能访问到构造函数中的属性,和情况1完全相反,结果相当于没有返回值。所以需要判断下返回的值是不是一个对象,如果是对象则返回这个对象,不然返回新创建的
obj
对象。所以实现代码如下:
【进阶3-4期】思考题解
问题:用 JS 实现一个无限累加的函数
add
,示例如下:实现:
我们知道打印函数时会自动调用
toString()
方法,函数add(a)
返回一个闭包sum(b)
,函数sum()
中累加计算a = a + b
,只需要重写sum.toString()
方法返回变量a
就OK了。参考
进阶系列目录
交流
进阶系列文章汇总如下,内有优质前端资料,觉得不错点个star。
https://github.com/yygmind/blog
我是木易杨,网易高级前端工程师,跟着我每周重点攻克一个前端面试重难点。接下来让我带你走进高级前端的世界,在进阶的路上,共勉!