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
// Otaku 御宅族,简称宅functionOtaku(name,age){this.name=name;this.age=age;this.habit='Games';}// 因为缺乏锻炼的缘故,身体强度让人担忧Otaku.prototype.strength=60;Otaku.prototype.sayYourName=function(){console.log('I am '+this.name);}varperson=newOtaku('Kevin','18');console.log(person.name)// Kevinconsole.log(person.habit)// Gamesconsole.log(person.strength)// 60person.sayYourName();// I am Kevin
从这个例子中,我们可以看到,实例 person 可以:
访问到 Otaku 构造函数里的属性
访问到 Otaku.prototype 中的属性
接下来,我们可以尝试着模拟一下了。
因为 new 是关键字,所以无法像 bind 函数一样直接覆盖,所以我们写一个函数,命名为 objectFactory,来模拟 new 的效果。用的时候是这样的:
functionOtaku(name,age){this.name=name;this.age=age;this.habit='Games';}Otaku.prototype.strength=60;Otaku.prototype.sayYourName=function(){console.log('I am '+this.name);}functionobjectFactory(){varobj=newObject(),Constructor=[].shift.call(arguments);obj.__proto__=Constructor.prototype;Constructor.apply(obj,arguments);returnobj;};varperson=objectFactory(Otaku,'Kevin','18')console.log(person.name)// Kevinconsole.log(person.habit)// Gamesconsole.log(person.strength)// 60person.sayYourName();// I am Kevin
JavaScript深入之new的模拟实现
new
一句话介绍 new:
也许有点难懂,我们在模拟 new 之前,先看看 new 实现了哪些功能。
举个例子:
从这个例子中,我们可以看到,实例 person 可以:
接下来,我们可以尝试着模拟一下了。
因为 new 是关键字,所以无法像 bind 函数一样直接覆盖,所以我们写一个函数,命名为 objectFactory,来模拟 new 的效果。用的时候是这样的:
初步实现
分析:
因为 new 的结果是一个新对象,所以在模拟实现的时候,我们也要建立一个新对象,假设这个对象叫 obj,因为 obj 会具有 Otaku 构造函数里的属性,想想经典继承的例子,我们可以使用 Otaku.apply(obj, arguments)来给 obj 添加新的属性。
在 JavaScript 深入系列第一篇中,我们便讲了原型与原型链,我们知道实例的 __proto__ 属性会指向构造函数的 prototype,也正是因为建立起这样的关系,实例可以访问原型上的属性。
现在,我们可以尝试着写第一版了:
在这一版中,我们:
更多关于:
原型与原型链,可以看《JavaScript深入之从原型到原型链》
apply,可以看《JavaScript深入之call和apply的模拟实现》
经典继承,可以看《JavaScript深入之继承》
复制以下的代码,到浏览器中,我们可以做一下测试:
[]~( ̄▽ ̄)~**
返回值效果实现
接下来我们再来看一种情况,假如构造函数有返回值,举个例子:
在这个例子中,构造函数返回了一个对象,在实例 person 中只能访问返回的对象中的属性。
而且还要注意一点,在这里我们是返回了一个对象,假如我们只是返回一个基本类型的值呢?
再举个例子:
结果完全颠倒过来,这次尽管有返回值,但是相当于没有返回值进行处理。
所以我们还需要判断返回的值是不是一个对象,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么就返回什么。
再来看第二版的代码,也是最后一版的代码:
下一篇文章
JavaScript深入之类数组对象与arguments
相关链接
《JavaScript深入之从原型到原型链》
《JavaScript深入之call和apply的模拟实现》
《JavaScript深入之继承》
深入系列
JavaScript深入系列目录地址:https://github.com/mqyqingfeng/Blog。
JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: