js原型和构造函数
前言
从应用层面深入理解原型模式和js中的构造函数。
构造函数(constructor)
js中的任何对象都有自己的构造函数。js中使用字面量声明的普通对象({})或数组([])等子对象本质上都是使用相关的函数做构造调用声明的。
// 等同于 var obj = {};
var obj = new Object();
// 等同于 arr = [];
var arr = new Array();
获取对象的构造函数:constructor是可读的,在对象上进行普通的属性访问(. / [])即可。
// 这里我们可以看到字面量语法声明的对象本质还是使用Object()构造的。var obj = {};
console.log(obj.constructor); // ƒ Object() { [native code] }
原型
显式原型prototype属性
prototype是函数的属性。每个函数被创建之后,都会拥有一个prototype属性,这个属性指向函数的原型对象。
function fn (){}
console.log(fn.prototype);
fn.prototype的原型在chrome下的输出。是一个对象,这个对象有一个显式的属性constructor(构造函数),它指向的是构造这个对象的函数。 还有一个隐式的属性,__proto__。

隐式原型__proto__属性
__proto__是对象的属性。每个对象被创建的时候都会拥有这个属性,这个属性指向的是,构造这个对象的函数的原型对象。
访问对象的__proto__属性:IE10以前无法识别__proto__属性,其他浏览器大部分都可以识别,可以输出但无法访问内部信心。ES5提供的Object.getPtotypeOf(obj) 可以获取指定对象的__proto__属性。
function fn (){}
var obj = new fn();
console.log(fn.prototype === Object.getPrototypeOf(obj)); // true
搞清楚prototype/__proto__/constructor之间的区别和联系
1,所有对象都有自己的构造函数(constructor),和一个隐式的原型属性(__proto__),__proto__指向的是这个对象的构造函数的原型。
2,所有的函数都有一个prototype属性这个熟悉指向的是构造函数的原型对象。
var obj = {};
// 这里的true不理解的话回头再看一遍之前的小例子,敲一下。理解这个true的话 原型这个部分的应用就没问题了。
console.log(obj.constructor.prototype === Object.getPrototypeOf(obj)); // true
原型链
原型链就是一个对象作为另一个对象的原型而存,而这个作为别人原型的对象还有自己的原型。
根对象
js中的所有对象都拓展于Object.prototype。 它是js中的顶层对象。在它之上没有其他的原型了。
var obj= {};
var objConstructor = obj.constructor;
// Object() 是使用js字面量创建的对象的构造函数。
console.log(objConstructor); // ƒ Object() { [native code] }
// Object.prototype是js中的根对象,在它之上没有其他原型了。
console.log(Object.getPrototypeOf(objConstructor.prototype)); // null
原型链的形成
关键就在于让一个对象成为另一个对象的原型。
Object.create(obj):返回一个把指定参数作为原型的新对象。
var obj= {name:"obj"};
var newObj = Object.create(obj);
console.log(newObj);
从chrome下的输出我们可以看到 形成了一个三层的原型链 newObject 中的隐式原型属性__proto__指向了obj,obj是使用字面量创建的普通对象,它本质上是使用Object()创建的。所以它指向的是根对象Object.prototype。

原型模式的执行流程
在对象本身查找要访问的属性和方法,如果没有,就到最近的原型上找,直接原型上没有,就到原型的原型上找,找到就直接返回,结束查找。一直找到Object.prototype上都没有,就返回undefined。
原型模式的应用
主要有两种,面向对象写法和任务委托写法。面向对象就是使用原型继承,多态都用的很少,使用起来也比较难理解。任务委托是在《你不知道的js》一书中看到的写法,设计上来看比强行面向对象要直观。但现在时代变了,ES6提供了Class语法糖,让面向对象的js程序可读性较好,便于理解。所以只了解一下任务委托写法。
面向对象
三大特征:封装,继承,多态。
好处:结构清晰,易维护,易拓展。
基于原型继承的面向对象
js中是没有传统面向类语言中的类和构造函数的,它使用new关键字配合普通函数模拟了构造函数,使用原型模拟类,让js拥有了继承和多态的能力。
面向对象写法:定义普通函数做构造调用,在函数的原型上提供实例共享的属性和方法。
任务委托:将数据和工具对象分开定义,让工具对象作为数据对象的原型。达到数据和逻辑分离,将任务处理委托给其他对象的目的。
var util = {
say:function(){
console.log(this.name);
}
}
var data = Object.create(util);
data.name = "键盘";
data.say(); // 键盘
小结:
1,每个对象都有自己的构造函数,可以通过constructor属性访问到。
2,每个对象都有一个隐式原型属性__proto__,可以使用Object.getPrototypeOf(obj)访问。
3,每个函数都有自己的原型对象,可以通过prototype属性访问。
4,对象的隐式原型属性(__proto__)指向的就是它的构造函数的原型(prototype)。
5,所有使用字面量创建的对象,本质上都是使用相关构造器函数构造出来的,函数是(Function()),数组是(Array())等等。
6,js中的Object是顶层函数它的prototype之上没有其他的原型了。js中所有对象的原型链的顶层几乎都是Object.prototype。
7,原型链就是对象做为其他对象的原型,的同时还有自己的原型。
8,原型模式的执行顺序就是首先在对象自有属性中查找,找不到就问原型有没有,原型没有就问原型的原型有没有,直到找到返回或找到顶层原型后返回undefined。
9,js中的面向对象就是基于原型模式在普通函数的原型上定义共享的属性和方法,达到继承的目的。
js原型和构造函数的更多相关文章
- 对js原型及构造函数的相关理解
一.js中的原型创建(声明)一个函数,浏览器在内存中会创建一个对象.每个函数都默认会有一个属性prototype指向了这个对象,就是说prototype的属性的值就是这个对象.此对象就是该函数的原型对 ...
- js原型和构造函数混合模式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JS原型、原型链、构造函数、实例与继承
https://cloud.tencent.com/developer/article/1408283 https://cloud.tencent.com/developer/article/1195 ...
- 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends
说实在话,以前我只需要知道"寄生组合继承"是最好的,有个祖传代码模版用就行.最近因为一些事情,几个星期以来一直心心念念想整理出来.本文以<JavaScript高级程序设计&g ...
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
- Js中关于构造函数,原型,原型链深入理解
在 ES6之前,在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但 ...
- 简单粗暴地理解js原型链--js面向对象编程
原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...
- JS原型链
JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...
- 【09-23】js原型继承学习笔记
js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...
随机推荐
- iPad actionsjeet
在iphone和ipad上使用UIActionShee控件t的效果会不一样,在苹果的官方文档中有相关说明: 在ipad上使用UIActionSheet控件改控件不再从底部弹出,而是从屏幕中间弹出与UI ...
- Spring Boot2.0之自定义参数
自定义参数,把不同环境的配置放到配置文件中去. 不同环境,如何区分配置文件信息,自定义配置文件信息 比如在 application.properties定义个参数 name=toov5 Spring ...
- 在IIS中某一个网站启用net.tcp
绑定 高级设置 http和net.tcp用逗号分隔 //擦擦擦,见鬼了,下面的是tcp.net导致我找了好久,都找不出这个错误 //一定要注意,不要写错了. 否则会收到提示:找不到具有绑定 NetT ...
- mooc_java 集合框架中 学生所选课程2Map&HashMap
Map&HashMapMap提供映射关系,元素以键值对形式存储,Map的键值对一Entry类型的对象实例形式存在,key值不能重复,value可以键最多能映射到一个值,支持泛型 Map< ...
- HDU 6170 Two strings (dp)
/** * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170 * 字符串match, '.'代表匹配任意一个字符,"*" 代表 ...
- linux命令学习笔记(44):top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管 理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷 ...
- HTml js 生成图片
<script type="text/javascript"> function $(id) { return document.getElementById(id); ...
- Swift协议
「协议」(protocol)声明一系列方法.属性.下标等用来约束其「遵循者」,进而保证「遵循者」能够完成限定的工作.「协议」本身不实现任何功能,它仅仅描述了「遵循者」的实现.「协议」能被类.结构体.枚 ...
- poj1475 Pushing Boxes[双重BFS(毒瘤搜索题)]
地址. 很重要的搜索题.★★★ 吐槽:算是写过的一道码量比较大的搜索题了,细节多,还比较毒瘤.虽然是一遍AC的,其实我提前偷了大数据,但是思路还是想了好长时间,照理说想了半小时出不来,我就会翻题解,但 ...
- 【Lintcode】136.Palindrome Partitioning
题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...