javascript原型原型链 学习随笔
理解原型和原型链。需从构造函数、__proto__属性(IE11以下这个属性是undefined,请使用chrome调试)、prototype属性入手。
JS内置的好多函数,这些函数又被叫做构造函数。如:Object---Array---Function---Date---String---Number---Boolean---Symbol---RegExp....
JS里,所有的对象,都是其构造函数的实例。如{}是Object的一个实例,[]是Array的一个实例。fn() {}是Function的一个实例...
(js的内置对象就不太清楚了。。如Math、JSON。只知道也是Object类型)。
一般情况,我们用对象字面量的方式创建Object的实例。
如:const obj = {}; 这种创建方式是完全等于const obj = new Object(); 当然字面量方式是推荐写法。
只要是函数,甭管构造不构造,都有一个prototype属性(指针,其指向函数的原型对象);该属性的值是一个对象,我们管它叫原型对象,其实它就是一个普通对象。对象该有的他都有。它还有个特殊的属性--constructor。属性值就是前面的函数。
关系图:

当调用构造函数创建实例时,实例内部将包含一个属性(指向其构造函数的原型对象的指针),在chrome、ff。这个属性是__proto__。这个属性的值是其构造函数的原型对象。


如上所示,obj是Object构造函数的一个实例,实例上有__proto__属性。这个属性值全等于Object构造函数的原型对象。
多亏有这个__proto__指针,我们在某构造函数的原型对象上定义的属性和方法都能被其所有的实例所共享。

在一些浏览器里(没错,就是IE),这个指针是不可见的。我们可以用 isPrototypeof()方法或者Object.getPrototypeOf()方法来判断实例与原型之间是否存在这种关系。

IE9以下就不支持Object.getPrototypeOf()方法了。
如果实例的 __proto__属性 或者叫 指向构造函数原型对象的指针 指向调用isPrototypeOf()方法的对象(Fn.prototype)。那么这个方法返回值是true。
这里一定要理解,实例的__proto__属性或者叫指向构造函数原型对象的指针是实实在在存在的,只不过有些浏览器给他取了个名字__proto__。有些浏览器没有去定义这个指针的名字。
Object.getPrototypeOf(fn1)方法返回的对象是fn1的构造函数的原型对象。
接下来就是原型链了
在js里。Object类型是基础类型,其他所有的引用类型都继承这个类型。
那么要怎么实现继承呢。
JS实现继承的方式主要就是通过原型链方法。
前面学习时,我们已经得知每个构造函数都有一个原型对象,构造函数的实例有一个指向原型对象的指针。
我们要做的就是。
把另外一个构造函数的实例赋值给原型对象。
首先,我们再定义一个函数Foo,此时Foo.prototype.__proto__ 全等于 Object.prototype;

(原型对象也是对象,自然也会有__proto__指针,如果没有去改它。默认就是指向Object.prototype呦)
接着。把另外一个构造函数的实例赋值给Foo.prototype。

显而易见,根据引用类型值的特性,Foo.prototype 和 fn1指向同一个对象。
这个对象的__proto__属性又指向其构造函数的原型对象。由此Foo函数的原型对象就包含了指向Fn的原型对象的指针。
即:Foo.prototype.__proto__ === Fn.prototype。
如果Fn的原型对象也是另外另外一个函数的实例。。。上述关系仍然成立,如此层层递进。一直指到Object.prototype。
这个对象就比较特殊了。它就没有__proto__属性。Object.prototype.__proto__ === null。原型链到此结束。
上图:

以上定义了两个函数。Person是超类型,Teacher子类型。人可以不是老师,但是老师一定是人嘛。哈哈哈。
属性的继承是通过
构造函数的this指向他的实例。通过call方法。把Person函数的this绑定到Teacher的实例xm,xh上。相当于xm.name = '小明';xh.name = ’小花‘;
方法的继承通过
这步实现了原型链关系。通过向原型链查找,只要存在于原型链上的方法,实例都能用。
确定原型和实例的关系
除了上面的isPrototypeOf()方法外,还有一个方法广为人知。就是使用Instance of 。
用这个操作符测试实例和原型链中出现过的构造函数。结果会返回true。

实现一个简单的instanceof操作符。
1.
Object.prototype.myInstanceOf = function (Func) {
if (typeof Func !== 'function') {
return false;
}
return Func.prototype.isPrototypeOf(this);
};
2.
Object.prototype.myInstanceOf = function (Func) {
if (typeof Func !== 'function') return false;
function _fn(instance, Func) {
if (instance.__proto__) {
if (instance.__proto__ !== Func.prototype) {
return _fn(instance.__proto__, Func);
} else {
return true;
}
}
return false;
}
return _fn(this, Func);
};
3.
Object.prototype.myInstanceOf = function (Func) {
if (typeof Func !== 'function') {
return false;
}
let _obj = Object.getPrototypeOf(this),
res = false;
while (_obj) {
if (_obj === Func.prototype) {
res = true;
break;
}
_obj = Object.getPrototypeOf(_obj);
}
return res;
};
结果:

也不知道有没有什么边界情况下的错误。。。
累死了。。
javascript原型原型链 学习随笔的更多相关文章
- JavaScript作用域、作用域链 学习随笔
(本文是这些知识点的自我理解.写之余从头回顾,加深理解.取得更多收获之用.) 作用域(scope) 程序设计概念,通常来说,一段程序代码中所用到的名字(JS叫标识符(如变量名.函数名.属性名.参数.. ...
- javaScript 原型与原型链学习笔记
javaScript中,原型是常用到一种方式,它能降低储存占用,写出更高效的代码 原型常用到的则是prototype属性 JavaScript prototype 属性 定义和用法 prototype ...
- javaScript系列 [04]-javaScript的原型链
[04]-javaScript的原型链 本文旨在花很少的篇幅讲清楚JavaScript语言中的原型链结构,很多朋友认为JavaScript中的原型链复杂难懂,其实不然,它们就像树上的一串猴子. 1.1 ...
- JavaScript prototype原型和原型链详解
用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...
- JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。
回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...
- Javascript的原型链图
90%的前端或者js程序员或者老师们对Javascript懂得不比这个多 给手机看的 但是这个图里的所有褐色单向箭头链就是Javascript的原型链(颜色标注对理解js原型链很关键) 这图中的各个_ ...
- javascript 之原型、原型链-14
原型 原型是一个对象,每个函数对象(在javascript 之对象中说过函数也是对象 )都有一个属性(prototype)指向这个对象--原型对象,这个对象的作用是让所有对象实例共享原型对象中的属性. ...
- 三张图搞懂JavaScript的原型对象与原型链
对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张 ...
- 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)
摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...
随机推荐
- 从0开始学爬虫2之json的介绍和使用
从0开始学爬虫2之json的介绍和使用 Json 一种轻量级的数据交换格式,通用,跨平台 键值对的集合,值的有序列表 类似于python中的dict Json中的键值如果是字符串一定要用双引号 jso ...
- web项目访问被拦截
如图,一启动就出现下图登录界面 原因很简单就是被拦截了.pom.xml中引入了下面的包,注释掉就可以了.当然如果用了shiro等权限框架也可能出现类似问题.谁copy进来的,盘他. <!-- h ...
- AD域策略启动关机脚本不执行的注意事项
其实主要是脚本路径的问题. 错误一: 直接使用右侧的添加按钮,添加了预控的本地路径.如上图第二行. 错误二: 直接使用右侧的添加按钮,添加了脚本的网络路径,如上图第三行. 正确的方法: 点击下方的显示 ...
- 线性回归:鸢尾花数据iris
# encoding: utf-8 from sklearn.linear_model import LogisticRegression import numpy as np from sklear ...
- CSS控制元素背景透明度总结
方法一:CSS3的background rgba filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColor ...
- iOS 多线程的简单理解(3)执行方式 + 执行对列 的组合
通过对前面两偏线程理解的总结,自己对线程的理解也逐渐加深,梳理的清晰起来…… 通常在使用线程 的时候,都是要用到 执行对列,执行方式,执行任务, 现在开始新一轮的深入 3. 1. 1 同步 + 串行 ...
- 【C/C++开发】C中调用C++函数
C中如何调用C++函数? 前阵子被问及一个在C中如何调用C++函数的问题,当时简单回答是将函数用extern "C"声明,当被问及如何将类内成员函数声明时,一时语塞,后来网上查了下 ...
- Meerkat软件
一.准备工作 meerkat 0.189版本和以前的版本相比,支持bwa mem 输出的bam文件,还支持全外显子数据count SV. meerkat原理 1.1 需要准备的软件 unix/Linu ...
- 软件素材---C/C++格式化显示当前时间--标准函数strftime
函数原型:size_t strftime (char* ptr, size_t maxsize, const char* format,const struct tm* timeptr ); 头文件: ...
- dotnet core JWT Demo
JWT介绍 JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.JWT的官网地址:https://jwt.io/. 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT令牌在 ...