关于JS call apply 对象、对象实例、prototype、Constructor、__proto__
关于call与apply的理解容易让人凌乱,这里有个方法可供参考
tiger.call(fox,arg1,arg2...)
tiger.apply(fox,[arg1,arg2...])
理解为
fox入侵者,是狡猾、邪恶的入侵者,乘tiger为难之际(召唤call\apply),成功欺骗tiger可怜的守卫(入口参数),入侵了tiger,
拥有了tiger的一切:财富、老婆、孩子... 可恨、可叹tiger英雄一世,如此落入宵小之手
关于函数对象、对象实例、prototype、Constructor、__proto__之间的关系如下图所示:
js完全可以面向对象开发,于是对象、对象继承、实例之间如何建立彼此的关系是javascript
语言必须要解决的问题,通过下面这张图,对象A、对象实例A1和A2,以及prototype、
constructor(构造函数)、__proto__之前是多么巧妙地结合起来组成一张关系网;
所以为了组成这个关系网,必须设立以下规则:
1.任何对象都有一个属性:prototype,这个属性的类型是对象
2. 任何对象实例都拥有constructor方法和__proto__属性
于是对象属性prototype用于关联Prototype(虚拟),对象实例化A1\A2...后,每个实例,包括Prototype
的constructor用于关联对象,同时为了能够动态共享prototype,每个实力的__proto__属性用于关联prototype
如此,这张关系网形成了;这实际是完美的抽象了客观世界:具备什么特质、能干什么、与其他个体是什么关系

引用一网友的实例、辅助理解
function base () {
this.arr = [];
}
function sub (){
}
sub.prototype= new base();
var a = new sub();
var b = new sub();
console.log(b.arr.length); //0
a.arr[0]='moersing';
console.log(b.arr.length); //1
可以看出,arr是一个共享的,如果说不适用this.arr而用 var arr = [] 的话,sub访问不到,只能通过父类的闭包来访问,但是问题还是存在的。如果想继承一个完全独立的引用类型:
第一 :
function base () {
this.arr = [];
}
function sub (){
base.call(this);// 先加上一个实例属性
}
sub.prototype= new base();
var a = new sub();
var b = new sub();
console.log(b.arr.length); //0
a.arr[0]='moersing';
console.log(b.arr.length); //0
console.log(a.arr.length); //修改了a,b不受影响
这个问题可以解决,但是不完美,可以看出, a和b有一个实例属性arr和一个prototype的arr,也就是说。
a.arr[0] = 'moersing' ;
console.log(a.arr.length); //1
delete a.arr; //把属性实例干掉
console.log(a.arr.length);// 这个时候访问的是 prototype的。
所以,理论上来讲,这并不能算是完美的,变量也是需要内存的不是吗?好OK,那么,接下来,使用另一种,上面那个叫 借用继承。
接下来这种方式比较完美,但是也不是那么复杂,主要是使用借用继承的思想罢了,也就是说,借用实例和借用原型分开。
function base() {
this.arr = [];
}
base.Constructor = function () { //添加一个原型构造函数
//这里判断一下,如果是一个函数,并且不是一个正则表达式对象,IE7会把正则反映成一个function而不是一个object
if (typeof this === 'function' && typeof this.prototype.source === 'undefined') {
var fn = this.prototype;
fn.name = 'moersing';
fn.age = '18';
fn.getFull = function () {
console.log(this.name + '|' + this.age);
};
}
else {
throw new TypeError('this is not a function');
}
};
function sub() {
base.call(this); //借用构造函数,实例化一个实例属性
}
base.Constructor.call(sub); //再调用父类的方法,构造出一个prototype的。
var a = new sub();
var b = new sub();
a.arr[0] = 'moersing'; //给a实例的引用类型添加一个元素
console.log(a.arr.length); //结果是1
console.log(b.arr.length); //结果是0,也就是没有收到影响
console.log(a.name); //打印a.prototype的属性
console.log(b.name); //打印b.prototype的属性
b.name = 'linfo'; //修改b的。
console.log(b.name); //linfo
console.log(a.name); //a没有影响,还是moersing
a.getFull(); //moerisng|18
b.getFull(); //linfo |18
关于JS call apply 对象、对象实例、prototype、Constructor、__proto__的更多相关文章
- prototype/constructor/__proto__之prototype简单应用
一.简单使用构造原型加prototype造简单的轮子. 1.想jQ那样获取HTML元素,先看JS代码 function Cmf() { //创建构造函数 this.arry = [] } Cmf.pr ...
- 原型模式Prototype,constructor,__proto__详解
最近由于在找工作,又拿起<JavaScript高级程序设计>看了起来,从中也发现了自己确实还是有很多地方不懂,刚刚看到原型模式这里,今天终于搞懂了,当然,我也不知道自己的理解是否有错. 1 ...
- prototype/constructor/__proto__之constructor。
1.constructor的字面意思就是构造.它是对象的一个属性,它对应的值是该对象的“构造者” //一.构造函数实例化的对象的constructor function Cmf(n,m){ this. ...
- prototype/constructor/__proto__之prototype
1任何对象都有__proto__属性 属性值Object2并不是所有对象都有prototype属性.只有方法对象(构造函数)以及基本数据类型还有Array,有prototype属性;并且所有方法(对象 ...
- 理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...
- 【转】理解js中的原型链,prototype与__proto__的关系
说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...
- [转]理解js中的原型链,prototype与__proto__的关系
本文转自:http://rockyuse.iteye.com/blog/1426510 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script typ ...
- prototype constructor __proto__
constructor, prototype, __proto__ 详解
- 为什么实例没有prototype属性?什么时候对象会有prototype属性呢?
为什么实例没有prototype属性?什么时候对象会有prototype属性呢? javascript loudou 1月12日提问 关注 9 关注 收藏 6 收藏,554 浏览 问题对人有帮助,内容 ...
- [Javascript] js的类和对象
类 graph LR 类-->构造函数 类-->prototype对象 类-->instanceof运算符 类-->constructor属性 类-->isPrototy ...
随机推荐
- Kafka 0.11客户端集群管理工具AdminClient
很多用户都有直接使用程序API操作Kafka集群的需求.在0.11版本之前,kafka的服务器端代码(即添加kafka_2.**依赖)提供了AdminClient和AdminUtils可以提供部分的集 ...
- socket 中文man页面函数
Linux 套接字的用户接口. 这个 BSD 兼容套接字是介于用户进程与内核网络协议栈之间的统一接口, 各协议模块属于不同的 协议族 ,如 PF_INET, PF_IPX, PF_PACKET 和 套 ...
- JLINK与JTAG的区别(转)
调试ARM,要遵循ARM的调试接口协议,JTAG就是其中的一种.当仿真时,IAR.KEIL.ADS等都有一个公共的调试接口,RDI就是其中的一种,那么我们如何完成RDI-->ARM调试协议(JT ...
- iOS - 布局NSLayoutConstraint动画的实现
抛出问题:为何在用到用到constraint的动画时以下代码无法实现动画的功能 ,没有动画直接刷新UI跳到80 - (void)touchesBegan:(NSSet<UITouch *> ...
- 如何在浏览器中简单模拟微信浏览器(仅限于通过User Agent进行判断的页面)
模拟微信浏览器: .打开360极速 .F12开发者工具 .开发者模式左上方有一个手机样子的图标 点击进入 设备模式‘ .将UA选项中的字符串替换成: Mozilla/ 备注: 替换的字符串是微信浏览器 ...
- 【linux】nginx options 跨域问题 请求HTTP错误405 用于访问该页的HTTP动作未被许可 Method Not Allowed
JavaScript JS 跨域问题 HTTP 错误 405 - 用于访问该页的 HTTP 动作未被许可HTTP 错误 405.0 - Method Not Allowed Nginx 处理跨域问题. ...
- Esper学习之十四:Pattern(一)
1. Pattern Atoms and Pattern operatorsPattern是通过原子事件和操作符组合在一起构成模板.原子事件有3类,操作符有4类,具体如下: 原子事件:1). 普通事件 ...
- git-常用命令一览表
一.git bash 操作文件 常用命令表 git常用 文件操作 命令 功能分类 命令 说明 备注 目录切换 cd 文件目录 改变/切换 目录, change directory 如 cd e:\ff ...
- ios-toolchain-based-on-clang-for-linux
https://github.com/tpoechtrager/cctools-port.git https://www.embtoolkit.org
- EF---延迟加载技术
延迟加载: 优点:只在需要的时候加载数据,不需要预先计划,避免了各种复杂的外连接.索引.视图操作带来的低效率问题 使用方式:两步 第一:在需要延迟加载的属性前加上virtual ,该属性的类型可以是任 ...