Javascript基础之-原型(prototype)
首先呢,prototype是对象里的一个内置属性,并且呢,这个属性是对于其他对象的一个引用。所以呢,思考下面的例子:
var obj = {a: 2
}
var myObj = Object.create(obj);
console.log(myObj.a); // 2
console.log(myObj === obj); // false
console.log(Object.getPrototypeOf(myObj) === obj); // true
Object.getPrototypeOf(myObj).a = 4
console.log(obj.a); // 4
这里可以看到,实际上Object.create()是新建了一个对象,并且这个对象的prototype是obj的一个引用,所以呢,如果咱们直接修改prototype里面的值,原对象也就跟着变了。
很简单吧,那么如果执行如下代码的话,会发生什么呢?
myObj.a = 10;
是不是认为,还跟上面那个一样的,obj.a也变成10了呢?实际上不是的,他的运行机制要比咱们想的稍微复杂一点点。
实际上要分三种情况来看:
如果在prototype链上存在这个属性,并且没有标记为只读,那么就会在本对象上新建一个新的同名属性。
如果在prototype链上存在这个属性,并且标记为只读,那么将无法修改已有属性或在本对象上新建一个同名属性,如果是严格模式的话,还会报错。
如果在prototype链上只是存在此setter,那么一定会调用此setter,并不会添加属性到对象上,更不会重新定义这个setter
很枯燥是吧,来看例子,对照着上面的情况,好好的理解一下:
var obj = {a: 2,set c(num) {console.log('exec it');}
}
var myObj = Object.create(obj);
myObj.a = 10;
console.log(obj.a); // 2
console.log(myObj.a); // 10
Object.defineProperty(obj, 'b', {value: 3,writable: false
})
myObj.b = 10;
console.log(myObj.b); // 3
myObj.c = 20; // "exec it"
console.log(myObj.c); // undefined
假如上面的已经理解了,那么可以思考下下面的运行结果:
var obj = {a: 2
}
var myObj = Object.create(obj);
console.log(++myObj.a); // 3
console.log(obj.a); // 2
这个在咱们实际的编码中时有发生,看代码是想把a改成3,但是由于上面第一种情况的影响,实际上是新建了一个同名属性3,并且赋值给了myObj。
上面我们谈论的都是普通对象的prototype的一些特性,接下来,咱们就要讲关于new关键字相关的一些知识点了,思考下面的例子
function Foo() {}
var a = new Foo();
console.log(Object.getPrototypeOf(a) === Foo.prototype); // true
var b = new Foo();
Object.getPrototypeOf(b).saySomething = function () {console.log('say something');
}
a.saySomething(); // "say something"
很明显,在new的过程中呢,生成了一个新对象,并且把Foo.prototype引用到了新对象的prototype。那么因为是引用,所以通过b改变其原型上的prototype的值,Foo.prototype里也会跟着改变。
那么new的过程,是不是一定引用的是函数的prototype呢?也不一定,比如说下面的例子。
function Foo() {return {a: 3}
}
var a = new Foo();
console.log(Object.getPrototypeOf(a) === Foo.prototype); // false
console.log(Object.getPrototypeOf(a) === Object.prototype); // true
console.log(a.a); // 3
在这个例子中,由于new的时候,返回的是一个对象,所以最后实际上a最终引用的是Foo最后返回的那个小对象,所以其prototype就是Object.prototype,而不是Foo.prototype
甚至说,Foo.prototype也是可以被改变的,不过在这时候,new出来的对象,其prototype就是被改过的那个对象。
var protoObj = {b: 10
}
function Foo() {}
Foo.prototype = protoObj;
var a = new Foo();
console.log(Object.getPrototypeOf(a) === Foo.prototype); // true
console.log(Object.getPrototypeOf(a) === protoObj); // true
console.log(a.b); // 10
你看,如果prototypeObj修改了默认的Foo.prototype,所以最后,实际上形成了这么一个引用链:a.prototype => foo.prototype => protoObj=>Object.prototype。
所以说结论吧,在new的时候,实际上执行会包含这么几步,
如果有return并且返回的是一个对象的话,则直接返回return后的那个对象。
反之,则新建一个对象。
并且吧函数的prototype引用到新建对象的prototype中。
所以说,原型,可以理解为我本来对象有一个prototype,引用着其他的对象,当我这个对象的prototype引用了另一个对象的prototype,一般情况会到Object.prototype为止,这样就组成了一个原型链,原型链也就是互相引用的引用链。而这个引用链是可以根据自己的需求去改。
好了,简短的一小节就完事了,如果有不明白的,或者有疏漏的地方,或者有什么地方想和我讨论的,可以留言给我哦。
本文转载自http://www.lht.ren/article/8/
Javascript基础之-原型(prototype)相关推荐
- JavaScript中的原型(prototype)与继承
在JavaScript中,原型是用来模仿其他「类」语言继承机制的基础.原型并不复杂,原型只是一个对象. 一.原型对象 1.1 什么是原型对象 每当我们创建了一个函数后,这个函数就拥有了一个protot ...
- 前端面试知识点总结JavaScript基础之原型和原型链(二)
一.JavaScript基础 原型和原型链 1.理解原型设计模式以及JavaScript中的原型规则 设计模式 1.工厂模式:在函数内建立一个对象,给对象赋予属性及方法再将对象返回设计模式. func ...
- 浅谈JavaScript中的原型prototype
之前看过一些关于原型的知识,但总是看了以后没有及时应用,导致再看到一些代码是遇到还是搞不清楚,借此机会谈一下我对prototype的理解. 1.再谈原型之前,我们要知道什么是构造器函数,型如下例: f ...
- 【一天时间|JavaScript基础】原型和原型链
一天时间系列文章是博主精心整理的面试热点问题和难点问题,吸收了大量的技术博客与面试文章,总结多年的面试经历,带你快速并高效地审视前端面试知识.直击技术痛点,主动出击,精密打击,这才是面试拿到高薪的秘诀 ...
- JavaScript中的原型prototype及原型链
原型prototype 简介: prototype里面放置了一种类的公用的方法(构造函数:constructor)和类的信息.因此可以用来作为一种类的共享数据实现机制.这种共享的另一个好处的是减少了内 ...
- (转)【javascript基础】原型与原型链
原文地址:http://www.cnblogs.com/allenxing/p/3527654.html 前言 原型是什么 理解原型对象 原型对象 isPrototypeOf hasOwnProper ...
- 说一说JavaScript 中的原型ProtoType
一时兴起,写一遍博客吧. "函数是函数,函数也是对象" 相信学过js 的同学看到这句话很熟悉.我表示耳朵都听出茧子了. 我们都知道,在JavaScript中是没有类的概念的,那么怎 ...
- 浅谈JavaScript对象的原型prototype
前提: 在JavaScript中一切皆对象,分为普通对象和函数对象,每个对象都有原型(undefined和null没有原型,所以undefined和null也就没有toSting方法). Object ...
- 夯实JavaScript基础之prototype, __proto__, instanceof
function New(f){return function(){var o = {'__proto__': f.prototype};f.apply(o, arguments);return o; ...
最新文章
- Oracle12c多租户如何启动关闭CDB或PDB (PDB自动启动)
- matlab 图片转换
- EBB-11、Linux启动流程
- 我的爱好html子页模板,我的爱好
- apollo修改配置刷新bean_技术文档丨Apollo软件概述
- Hive的列分隔符和行分隔符
- json java的set函数,JsonConfig的jsonConfig.setExcludes的用法
- 【大数据】通过女票的淘宝历程,大白话讲解大数据各个方向的分工
- HTML网站去色代码
- 需求与商业模式分析-2-商业模式类型
- matlab函数sinh,matlab sinh 使用方法
- html pc页面连接到微信,PC上对限制在微信客户端访问的html页面进行调试
- 南朝皇帝简介-20170604
- 安卓(Android)手机如何安装APK?
- android手机传文件,Android手机间如何高速互传文件?
- 【论文阅读】MPViT : Multi-Path Vision Transformer for Dense Prediction
- 计算机类图书的中国法类号,公共书目查询
- 每日新闻:阿里云掀起新一轮价格大战;比特大陆正式发布AI芯片;百度区块链实验室落户海南;救市意图明显 北京海淀区成立百亿纾困基金...
- 2021年12月10日
- windows安装pscp工具,通过命令行上传到linux服务器
热门文章
- Python filter 函数 - Python零基础入门教程
- 通过docker无法访问到tomcat报页面404
- php时间转分钟前,PHP把时间转换成几分钟前几小时前几天前
- 娄底八中的初中计算机考试,众人同心勤耕耘 敢叫日月换新天
- xrdpdf卡片在哪可下载_暑假学习英语字母,就是这样简单(附可打印字母卡下载)...
- MySQL read-c_技术分享 | MySQL C API 参数 MYSQL_OPT_READ_TIMEOUT 的一些行为分析
- 计算机软件应用员,济宁计算机办公应用软件操作员
- php 内容编码错误,PHP输出缓冲,ob_gzhandler引起的内容编码错误?
- koa mysql mongodb_koa 操作MongoDB数据库
- android动画放大后缩小,Android 补间动画 scale(缩放)