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 ...
随机推荐
- 解读 CSS 布局之水平垂直居中
对一个元素水平垂直居中,在我们的工作中是会经常遇到的,也是CSS布局中很重要的一部分,本文就来讲讲CSS水平垂直居中的一些方法.由于我们大搜车的日常工作中已经不再需要理会低版本IE,所以本文所贴出的方 ...
- blog首页视图
声明:此Django分类下的教程是追梦人物所有,地址http://www.jianshu.com/u/f0c09f959299,本人写在此只是为了巩固复习使用 django 是如何处理 http 请求 ...
- promise介绍
promise简介 Promise的出现,原本是为了解决回调地狱的问题.所有人在讲解Promise时,都会以一个ajax请求为例,此处我们也用一个简单的ajax的例子来带大家看一下Promise是如何 ...
- 带动画效果的jQuery手风琴
带动画效果的jQuery特效手风琴是一款带动画效果的手风琴作品,非常实用,可以用在新闻列表.FAQ等模块,默认的是打开第一个选项,查看其它的时候直接点击加号按钮就展开. 源码地址:http://www ...
- kvm初体验之一:参考文档
KVM Virtualization in RHEL 6 Made Easy KVM Virtualization in RHEL 6 Made Easy – Part 2 RHEL 6 Virtua ...
- 【C】四则运算生成和核对器----by郁卓、谢明浩
[Github项目地址] 完成功能: 1. 使用 -n 参数控制生成题目的个数 2. 使用 -r 参数控制题目中数值(自然数.真分数和真分数分母)的范围 3. 生成的题目中计算过程不能产生负数,也就是 ...
- listen 63
Danger Explainers Convince Kids Better Than Do Edict Issuers An eight-year-old may view a hammer as ...
- appium 支持输入中文
加入: desired_caps['unicodeKeyboard'] = True desired_caps['resetKeyboard'] = True 使用输入中文: input_txt = ...
- poj1734Sightseeing trip——无向图求最小环
题目:http://poj.org/problem?id=1734 无向图求最小环,用floyd: 在每个k点更新f[i][j]之前,以k点作为直接连到i,j组成一个环的点,这样找一下最小环: 注意必 ...
- poj2955——括号匹配
题目:http://poj.org/problem?id=2955 区间DP. 代码如下: #include<iostream> #include<cstdio> #inclu ...