Javascrip—proto__与prototype(11)
prototype
prototype是一个拥有 [[Construct]] 内部方法的对象才有的属性。
例如函数,对象的方法,ES6 中的类。注意 ES6 中的箭头函数没有 [[Construct]] 方法,因此没有prototype这个属性,除非你为它添加一个。
当创建函数时,JavaScript 会为这个函数自动添加prototype属性,这个属性指向的是一个原型对象Functionname.prototype。我们可以向这个原型对象添加属性或对象,甚至可以指向一个现有的对象。
proto
接下来我们说说继承,每个对象都有一个__proto__属性,这个属性是用来标识自己所继承的原型。
注意: JavaScript 中任意对象都有一个内置属性 [[Prototype]] ,在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。以下统一使用__proto__来访问 [[Prototype]],在实际开发中是不能这样访问的。
原型链
JavaScript 可以通过prototype和__proto__在两个对象之间创建一个关联,使得一个对象就可以通过委托访问另一个对象的属性和函数。
这样的一个关联就是原型链,一个由对象组成的有限对象链,用于实现继承和共享属性。
构造函数创建对象实例
JavaScript 函数有两个不同的内部方法:[[Call]] 和 [[Construct]] 。
如果不通过new关键字调用函数,则执行 [[Call]] 函数,从而直接执行代码中的函数体。
当通过new关键字调用函数时,执行的是 [[Construct]] 函数,它负责创建一个实例对象,把实例对象的__proto__属性指向构造函数的prototype来实现继承构造函数prototype的所有属性和方法,将this绑定到实例上,然后再执行函数体。
模拟一个构造函数:
function createObject(proto) {
if (!(proto === null || typeof proto === "object" || typeof proto === "function"){
throw TypeError('Argument must be an object, or null');
}
var obj = new Object();
obj.__proto__ = proto;
return obj;
}
var foo = createObject(Foo.prototype);
至此我们了解了prototype和__proto__的作用,也了解使用构造函数创建对象实例时这两个属性的指向,以下使用一张图来总结一下如何通过prototype和__proto__实现原型链。
从上图我们可以找出foo对象和Foo函数的原型链:
foo.__proto__ == Foo.prototype;
foo.__proto__.__proto__ == Foo.prototype.__proto__ == Object.prototype;
foo.__proto__.__proto__.__proto__ == Foo.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null;
Foo.__proto__ == Function.prototype;
Foo.__proto__.__proto__ == Function.prototype.__proto__;
Foo.__proto__.__proto__.__proto__ == Function.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null;
构造函数Foo的原型链上没有Foo.prototype,因此无法继承Foo.prototype上的属性和方法。而实例foo的原型链上有Foo.prototype,因此foo可以继承Foo.prototype上的属性和方法。
到这里,我们可以很简单的解答小英童鞋的问题了,在Foo的原型链上没有Foo.prototype,无法继承Foo.prototype上的combineName方法,因此会抛出Foo.combineName is not a function的异常。要想使用combineName方法,可以这样Foo.prototype.combineName.call(this),或者这样this.combineName()(this指向实例对象)。
到此本文结束
这里推荐一下我的前端学习交流群:731771211,里面都是学习前端的,群里会不定期更新最新的教程和学习方法,有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的web前端党欢迎加入。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Java序列化 ObjectInputStream源码解析
上一篇讲了类的序列化,今天要讲类的反序列化,ObjectInputStream。 从内部变量中我们可以看出,内部包含一个块输入流,因为有handle机制所以也有一个内部缓存表但不是hash表 /** 处理数据块转换的过滤流 */ private final BlockDataInputStream bin; /** 确认调用返回列表 */ private final ValidationList vlist; /** 递归深度 */ private long depth; /** 对任何种类的对象、类、枚举、代理的引用总数 */ private long totalObjectRefs; /** 流是否关闭 */ private boolean closed; /** 线柄->obj/exception映射 */ private final HandleTable handles; /** 传递句柄值上下调用栈的草稿区 */ private int passHandle = NULL_HANDLE; /** 当在字段值末尾因没有TC_ENDBLOCKDATA阻塞时设置的标志 */...
-
下一篇
Javascrip—关于this绑定机制的解析(12)
在《你不知道的JavaScript》里面关于this绑定机制的部分讲的特别好,很清晰,这部分对我们js的使用也是相当关键的,并且这也是一个面试的高频考点,所以整理一篇文章分享一下这部分的内容,相信看本文的解析,你一定会有所收获的为什么要用this: function identify() { console.log("Hello,I'm " + this.name); } let me = { name: "Kyle" }; let you = { name: "Reader" }; identify.call(me); // Hello,I'm Kyle identify.call(you); // Hello,I'm Reader 这个简单的栗子,可以在不同的对象中复用函数identify,不用针对每个对象编写一个新函数。 this解决的问题: this提供了一种更优雅的方法来隐式'传递'一个对象的引用,因此可以将API设计得更加简洁并且易于复用。 this的四种绑定规则: 默认绑定: 规则:在非严格模式下,默认绑定的this指向全局对象,严格模式下this指向undefined ...
相关文章
文章评论
共有0条评论来说两句吧...