博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的JS笔记 -- 原型
阅读量:5848 次
发布时间:2019-06-19

本文共 2777 字,大约阅读时间需要 9 分钟。


每个函数对象都有一个prototype属性,这个属性这个属性是一个指针,指向一个对象。当函数作为构造函数使用时这个对象会成为调用该构造函数而创建的实例的原型,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

就是说,构造函数生成的实例会有一组共享的属性和方法,这些属性和方法在构造函数的原型对象里。

function F(val) {	this.a = val;}F.prototype.sayA = function () {	console.log(this.a);}var f1 = new F(1);var f2 = new F(2);// 由F函数生成的实例都会包含sayA方法f1.sayA();f2.sayA();复制代码

prototype

只要创建一个新函数,就会创建一个prototype属性,这个属性指向原型对象。原型对象初始只包含constructor属性,指向构造函数。

function F(val) {	this.a = val;}typeof F; // 'function',构造函数也是函数类型// 上面的构造函数的默认prototype类似下面F.prototype = {	constructor: F};// 当需要在默认原型上添加属性和方法时|,就像在一个已经创建好的对象上添加新属性一样F.prototype.b = 2;F.prototype.sayA = function () {	console.log(this.a);}var f1 = new F(1); // 重写原型之前创建的实例,拥有原来的属性和方法f1.sayA(); // 1f1.sayB(); // f1.sayB is not a function// 但如果像下面这样:// 这种写法相当于将原型对象的引用指向一个新的对象,这样的话原来的原型对象就丢失了,用这个新对象替代。添加在原来原型对象上的属性和方法也就无效了。F.prototype = {	// 重写之后如果没有添加constructor属性,constructor属性也会丢失	b: 3,	sayB: function () {		console.log(this.b);	}}// 重写原型之后constructor属性丢失,如果需要,可以添加一个Object.defineProperty(F.prototype, 'constructor', {    enmumerable: false, // constructor属性不可枚举    value: F // 设定需要指向的构造函数}); var f2 = new F(1); // 在重写原型之后创建的实例,拥有新的属性和方法f2.sayA(); // f1.sayA is not a functionf2.sayB(); // 3// 产生这两种情况的原因其实就是执行上下文。复制代码
  • 原型方法:

    • proObj.isPrototypeOf(obj),判断proObj是否是obj的原型对象,是返回true,反之false

      Object.prototype.isPrototypeOf({}); // true复制代码
    • Object.getPrototypeOf(obj),获取obj的原型对象

      Object.getPrototypeOf({}); // Object.prototype复制代码
  • 原型规则:

    • 对象实例只能读取原型对象中的属性和方法,但不能改写、删除或添加;
    • 对象实例搜索属性和方法,会先搜索实例再搜索原型链,如果实例中存在,就会屏蔽原型中的同名属性或方法;

原型链

原型链,是JS实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

我们知道构造函数、原型和实例之间有如下关系:每个构造函数都有一个原型对象(prototype),原型对象都有一个指向构造函数的指针(constructor),而实例对象都包含一个指向原型对象的内部指针( [[Prototype]] )

[[Prototype]]是一个JS内置属性就是 ,理解原型链,就得先理解[[Prototype]];每个**对象(除null)**都有[[Prototype]]属性,指向其构造函数的原型对象,是不可见的。

在浏览器中 [[Prototype]]属性就是 __proto__

正因为[[Prototype]]指向构造函数的原型对象,对象才能获取构造函数原型上的属性和方法。然后原型对象也是一个对象,它也有[[Prototype]]属性指向它的构造函数的原型对象,这样就构成了原型链。

所以[[Prototype]]是实现原型链的基础

[[Prototype]]有个特殊值,就是Object.prototype对象也有[[Prototype]]属性,值为null,处于原型链的最顶层。

// 浏览器环境下例子,[[Prototype]]就是__proto__:var f = { // 字面量创建一个对象,相当于调用Object构造函数创建对象	a: 1}; // 原型链: f --__proto__--> Object.prototype --__proto__--> nullfunction A() {	this.a = 1;}A.prototype.sayA = function () {	console.log(this.a);};var a = new A();// 原型链: a --__proto__--> a.prototype --__proto__ --> Object.prototype --__proto__ --> nullfunction B() {	this.b = 2;} B.prototype = new A();var b = new B();// 原型链:b --__proto__--> B.prototype --__proto__ --> A.prototype --__proto__ --> Object.prototype --__proto__ --> null复制代码

实例对象会按照原型链的顺序搜索属性或方法。

更多文章在 ,觉得不错希望点个

写在最后:

我只是一个自学JS的初学者,笔记是学习时各处收集的,有一些是我自己的理解。但是不少知识来自分享到网络的大神们,因为实在不知道我在哪里使用了谁的文章,所以只能统一的表达一下我的感谢! 文章里边可能有的地方会有错误,如果发现,可以留言提醒我。

转载于:https://juejin.im/post/5a3138ff51882503dc53b575

你可能感兴趣的文章
Android命令Monkey压力测试,详解
查看>>
负载均衡(LB)集群 dr
查看>>
(转)直接拿来用!最火的iOS开源项目(一)
查看>>
div+css+js 树形菜单
查看>>
android EventBus 3.0 混淆配置
查看>>
我的友情链接
查看>>
DNS区域委派与转发
查看>>
Windows Server 2008 RemoteApp---发布应用程序
查看>>
白帽子技术分析会话劫持实战讲解
查看>>
我的友情链接
查看>>
yum的三种方式
查看>>
Redis分布式缓存安装和使用
查看>>
PHP环境搭建:Windows 7下安装配置PHP+Apache+Mysql环境教程以及注意事项
查看>>
20天精通 Windows 8:系列课程资料集
查看>>
html5 <figure> 标签
查看>>
linux的I/O多路转接select的fd_set数据结构和相应FD_宏的实现分析
查看>>
Mysql数据库InnoDB存储引擎的隔离级别
查看>>
开源监控软件 Hyperic 的两种插件
查看>>
TOMCAT
查看>>
无土栽培中的物联网技术应用
查看>>